twain3.0/huagao/huagaods.cpp

3222 lines
119 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.

#include "stdafx.h"
#ifdef max
#undef max
#endif
#ifdef min
#undef min
#endif
#include <memory>
#include "huagaods.hpp"
#include "twglue.hpp"
#include "resource.h"
#include "CTwainUI.h"
#include "CIndicatorDlg.h"
//#include "Cmsgbox.h"
#include "Device/PublicFunc.h"
#include "Device/GScanO200.h"
#include "Device/GScanO400.h"
#include "Device/GScanO400Android.h"
#include "Device/GScanO1003399.h"
#include "Device/GScan439Android.h"
#include "Device/filetools.h"
#include "Device/GScanVirtual.h"
#include <list>
#include <map>
#include "GscanJsonConfig.h"
#include "G4Tiff.h"
#include "Device/UsbScanEx.h"
#ifdef WIN32
#include <Psapi.h>
#include <minidumpapiset.h>
#pragma comment (lib,"Dbghelp.lib")
#endif // WIN32
using namespace std;
//custom define caps enum
enum class CapTypeEx : unsigned short {
Base = 0x8000,//custom caps enum value must bigger than CapTypeEx::Base value,otherwise might make conflict
TwEx_IMultiOutputRed = 0x8026,
TwEx_IFillHole = 0x8018,
TwEx_IFillHoleRatio = 0x8092,
TwEx_IFillBackground = 0x8004,
TwEx_IBackRotate180 = 0x8005,
TwEx_IAutoDiscardBlankVince = 0x8091,
TwEx_IEnhanceColor = 0x8007,
TwEx_HardwareVersion = 0x8025,
TwEx_ScrewDetectEnable = 0x8006,
TwEx_ScrewLevel = 0x8021,
TwEx_Sharpen = 0x8022,
TwEx_EnFold = 0x8037,
TwEx_StableDetectEnable = 0x8090,
TwEx_UVModel = 0x8093,
TwEx_SwitchFrontBack = 0x8094,
TwEx_HsvCorrect = 0x8095,
TwEx_DogEarDelection = 0x8096,
TwEx_FillBackgroundMode = 0x8097,
TwEx_CroporDesaskewIndent = 0x8098,
TwEx_CropNoise = 0x8099,
TwEx_CroporDesaskewThreshold = 0x8100,
TwEx_IDetachNoise = 0x8101,
TwEx_IDetachNoiseValue = 0x8102,
TwEx_SizeDetect = 0x8103,
TwEx_LowPowerMode = 0x8104,
TwEx_ENCODE = 0x8105,
TwEx_CropModel=0x8106,
TwEx_DogEarDistance = 0x8107,
TwEx_ImageSplit = 0x8108,
TwEx_IFadeBack = 0x8109,
TwEx_IFadeBackValue = 0x8110,
TwEx_IToBeScan = 0x8111,
TwEx_IEnMultiOutPut = 0x8112,
TwEx_IEnMultiOutPutType = 0x8113,
TwEx_IFixedPaper = 0x8114,
TwEx_IHighImageQuality = 0x8115,
TwEx_SETTOKEN = 0x8116,
TwEx_IHsvFilter = 0x8117,
TwEx_ColorCast = 0x8118,
TwEx_IToBeScanTimeOut = 0x8119,
};
enum class PaperSizeEx : unsigned short {
K8 = 0x81,
K16 = 0x82,
Trigeminy = 0x83,
};
using namespace Twpp;
using namespace std::placeholders;
#define TWPP_ENTRY_MFC(SourceClass)\
extern "C" TWPP_DETAIL_EXPORT Twpp::ReturnCode TWPP_DETAIL_CALLSTYLE \
DS_Entry(Twpp::Identity* origin, Twpp::DataGroup dg, Twpp::Dat dat, Twpp::Msg msg, void* data){\
AFX_MANAGE_STATE(AfxGetStaticModuleState()); \
static_assert(\
std::is_base_of<Twpp::SourceFromThis<SourceClass, false>, SourceClass>::value ||\
std::is_base_of<Twpp::SourceFromThis<SourceClass, true>, SourceClass>::value,\
"Class " #SourceClass " is not derived from SourceFromThis."\
);\
return SourceClass::entry(origin, dg, dat, msg, data);\
}
TWPP_ENTRY_MFC(HuagaoDs)
static constexpr const Identity srcIdent(
Version(3, 3, Language::English, Country::China, "v3.3.5.9"),
DataGroup::Image,
#ifdef MAKEHUAGAO
"HUAGO",
#elif defined HANVON
"Hanvon",
#elif defined AUGE
"AUGE",
#elif defined LANXUM
"LANXUM",
#elif defiend ZHUOYUYUN
"ZHUOYUYUN",
#elif defined CUMTENN
"CUMTENN",
#elif defined MAKERIGHTWAY
"RIGHTWAY",
#elif defined NOLOGO
"SCAN",
#else // MAKEHUAGAO
"ZHIBEN",
#endif
#ifdef G200
#ifdef ISG100
#ifdef LANXUM
"G62S Series",
#elif defined HANVON
"HW-8000",
#elif defiend ZHUOYUYUN
"ZY-2100S",
#else // ISG100
"G100 Series",
#endif
#else // ISG100
#ifdef LANXUM
"G73S Series",
#elif defined HANVON
"HW-9000",
#elif defiend ZHUOYUYUN
"ZY-2100S",
#elif defined CUMTENN
"CTS A3",
#else // ISG100
"G200 Series",
#endif
#endif
#elif defined(G300) // G200
#ifdef LANXUM
"G42S Series",
#elif defined CUMTENN
"CTS A4",
#elif defiend ZHUOYUYUN
"ZY-2100S",
#elif defined HANVON
#ifdef ANDROIDSERIAL
"HW-1000",
#else
"HW-1000NS",
#endif // ANDROIDSERIAL
#else // ISG100
"G300 Series",//<2F><><EFBFBD>ݾɼ<DDBE><C9BC><EFBFBD> pm changed <20><>G300 Series
#endif
#elif defined(G400) // G200
#ifdef LANXUM
"G52S Series",
#elif defiend ZHUOYUYUN
"ZY-2100S",
#elif defined HANVON
#ifdef ANDROIDSERIAL
"HW-7000",
#else
"HW-7000NS",
#endif // ANDROIDSERIAL
#else // ISG100
"G400 Series",
#endif
#endif
#ifdef G200
#ifdef ISG100
#ifdef MAKEHUAGAO
"HUAGOSCAN G100 TWAIN"
#elif defined NOLOGO
"Scan G100 TWAIN"
#elif defined AUGE
"AUGESCAN G100 TWAIN"
#elif defiend ZHUOYUYUN
"ZHUOYUYUNSCAN G100 TWAIN"
#elif defined HANVON
"Hanvon HW-8000 TAWIN"
#elif defined LANXUM //!LANXUM
"LANXUMSCAN G62S TWAIN"
#else // !MAKEHUAGAO
"ZhibenScan G100 TWAIN"
#endif
#else // ISG100
#ifdef MAKEHUAGAO
"HUAGOSCAN G200 TWAIN"
#elif defiend ZHUOYUYUN
"ZHUOYUYUNSCAN G200 TWAIN"
#elif defined NOLOGO
"Scan G200 TWAIN"
#elif defined CUMTENN
"CUMTENN CTS A3 TWAIN"
#elif defined HANVON
"Hanvon HW-9000 TAWIN"
#elif defined LANXUM //!LANXUM
"LANXUMSCAN G73S TWAIN"
#else // !MAKEHUAGAO
"ZhibenScan G200 TWAIN"
#endif
#endif
#elif defined G300 // G200
#ifdef MAKEHUAGAO
#ifdef UV
"HUAGOSCAN G300UV TWAIN"
#elif defined ANDROIDSERIAL
"HUAGOSCAN G300 Android TWAIN"// <20><><EFBFBD>ݾɼ<DDBE><C9BC><EFBFBD> pm changed "HUAGOSCAN G300 TWAIN"
#else
"HUAGOSCAN G300 Linux TWAIN"
#endif
#elif defined UV && defined MAKERIGHTWAY
"RIGHTWAYSCAN G300 TWAIN"
#elif defined HANVON
#ifdef ANDROIDSERIAL
"Hanvon HW-1000 TAWIN"
#else
"Hanvon HW-1000NS TAWIN"
#endif // ANDROIDSERIES
#elif defined NOLOGO
"Scan G300 TWAIN"
#elif defiend ZHUOYUYUN
"ZHUOYUYUNSCAN G300 TWAIN"
#elif defined CUMTENN
"CUMTENN CTS A4 TWAIN"
#elif defined LANXUM //!LANXUM
"LANXUMSCAN G42S TWAIN"
#else // !MAKEHUAGAO
"ZhibenScan G300 TWAIN"
#endif
#elif defined(G400) // G200
#ifdef MAKEHUAGAO
#ifdef ANDROIDSERIAL
"HUAGOSCAN G400 Android TWAIN"
#else
"HUAGOSCAN G400 Linux TWAIN"
#endif // ANDROIDSERIES
#elif defined HANVON
#ifdef ANDROIDSERIAL
"Hanvon HW-7000 TAWIN"
#else
"Hanvon HW-7000NS TAWIN"
#endif // ANDROIDSERIES
#elif defined LANXUM //!LANXUM
"LANXUMSCAN G52S TWAIN"
#elif defiend ZHUOYUYUN
"ZHUOYUYUNSCAN G400 TWAIN"
#elif defined NOLOGO
"Scan G400 TWAIN"
#else // !MAKEHUAGAO
"ZhibenScan G400 TWAIN"
#endif
#endif
#if defined(_MSC_VER)
""
#elif defined(__GNUC__)
" GCC"
#elif defined(__clang__)
" CLang"
#endif
);
// lets just simulate uniform resolution for both axes
static constexpr UInt32 RESOLUTIONX = 85;
//static std::unique_ptr<CWinApp> application(new CWinApp());
#ifdef LANXUM
static list<float> resList = { 100.0,150.0,200.0,240.0,300.0 };
#else
static list<float> resList = { 100.0,150.0,200.0,240.0,300.0,600.0 };
#endif // LANXUM
//<2F><><EFBFBD><EFBFBD>G200 G300<30><30>G400ֽ<30>ŷ<EFBFBD><C5B7><EFBFBD>
#ifdef G200
static list<UInt16> paperSizeList = { (UInt16)PaperSize::A3,(UInt16)PaperSize::A4,(UInt16)PaperSize::A5,(UInt16)PaperSize::A6,
(UInt16)PaperSize::IsoB4,(UInt16)PaperSize::IsoB5,(UInt16)PaperSize::IsoB6,
(UInt16)PaperSize::UsLetter,(UInt16)PaperSize::UsLegal,(UInt16)PaperSize::UsLedger,
(UInt16)PaperSize::MaxSize,(UInt16)PaperSize::None,(UInt16)PaperSize::UsStatement,
(UInt16)PaperSizeEx::K8,(UInt16)PaperSizeEx::K16,(UInt16)PaperSizeEx::Trigeminy };
#elif defined G300
static list<UInt16> paperSizeList = { (UInt16)PaperSize::A4,(UInt16)PaperSize::A5,(UInt16)PaperSize::A6, (UInt16)PaperSize::IsoB5,(UInt16)PaperSize::IsoB6,
(UInt16)PaperSize::UsLetter,(UInt16)PaperSize::UsLegal,(UInt16)PaperSize::None,(UInt16)PaperSizeEx::K16 };
#elif defined G400
static list<UInt16> paperSizeList = { (UInt16)PaperSize::A3,(UInt16)PaperSize::A4,(UInt16)PaperSize::A5,(UInt16)PaperSize::A6,
(UInt16)PaperSize::IsoB4,(UInt16)PaperSize::IsoB5,(UInt16)PaperSize::IsoB6,
(UInt16)PaperSize::UsLetter,(UInt16)PaperSize::UsLegal,(UInt16)PaperSize::UsLedger,
(UInt16)PaperSize::MaxSize,(UInt16)PaperSize::None,(UInt16)PaperSize::UsStatement ,
(UInt16)PaperSizeEx::K8,(UInt16)PaperSizeEx::K16,(UInt16)PaperSizeEx::Trigeminy };
#endif // G200
static list<float> imageRotateList = { 0.0,90.0,180.0,270.0 };
enum class DeviceEventType : UInt16
{
CustomEvents = 0x8000,
Dev_OPENCOVER,
Dev_NOFEED,
Dev_FEEDERROR,
Dev_STABLE,
Dev_SKREW,
Dev_COUNTMOE,
Dev_HARDWAREERROR,
Dev_FPGAERROR,
Dev_UserStop,
Dev_DogEar
};
static map<unsigned int, DeviceEvent::Type> mapDeviceEvent = {
{OPEN_COVER,(DeviceEvent::Type)(DeviceEventType::Dev_OPENCOVER)},
{NO_FEED,(DeviceEvent::Type)(DeviceEventType::Dev_NOFEED)},
{FEED_IN_ERROR,(DeviceEvent::Type)(DeviceEventType::Dev_FEEDERROR)},
{PAPER_JAM,DeviceEvent::Type::PaperJam},
{DETECT_DOUBLE_FEED,DeviceEvent::Type::PaperDoubleFeed},
{DETECT_STAPLE,(DeviceEvent::Type)(DeviceEventType::Dev_STABLE)},
{PAPER_SKEW,(DeviceEvent::Type)(DeviceEventType::Dev_SKREW)},
{COUNT_MODE,(DeviceEvent::Type)(DeviceEventType::Dev_COUNTMOE)},
{HARDWARE_ERROR,(DeviceEvent::Type)(DeviceEventType::Dev_HARDWAREERROR)},
{FPGA_ERROR,(DeviceEvent::Type)(DeviceEventType::Dev_FPGAERROR)},
{USB_DISCONNECTED,DeviceEvent::Type::CheckDeviceOnline},
{USER_STOP,(DeviceEvent::Type)(DeviceEventType::Dev_UserStop)},
{DOG_EAR,(DeviceEvent::Type)(DeviceEventType::Dev_DogEar)}
};
struct Vid_pid
{
WORD vid;
WORD pid;
};
#ifdef LANXUM
static std::vector<Vid_pid> DeviceID{
{0x31c9,0x8200},
#ifdef G200
#ifdef ISG100
{0x31c9,0x8629},
{0x31c9,0x8620},
#else
{0x31c9,0x8739},
{0x31c9,0x8730},
#endif // ISG100
#elif defined G300
{0x31c9,0x8420},
{0x31c9,0x8429},
#elif defined G400
{0x31c9,0x8520},
{0x31c9,0x8529},
#endif // ISG100
};
#elif defiend ZHUOYUYUN
static std::vector<Vid_pid> DeviceID{
{0x3072,0x2100},
};
#elif defined AUGE
static std::vector<Vid_pid> DeviceID{
{0x3072,0x0130},
};
#elif defined HANVON
static std::vector<Vid_pid> DeviceID{
#ifdef G200
#ifdef ISG100
{0x2903,0x8000},
#else
{0x2903,0x9000},
#endif // ISG100
#elif defined G400
{0x2903,0x7000},
#ifdef ANDROIDSERIAL
{0x2903,0x7002},
#else
{0x2903,0x7039},
#endif // ANDROIDSERIAL
#elif defined G300
{0x2903,0x1000},
#ifdef ANDROIDSERIAL
{0x2903,0x1002},
#endif // ANDROIDSERIAL
#endif // G200
};
#elif defined CUMTENN
static std::vector<Vid_pid> DeviceID{
#ifdef G200
#ifdef ISG100
{0x3072,0x138},
#else
{0x3072,0x238},
#endif // ISG100
#elif defined G300
{0x3072,0x0303},
#elif defined G400
{0x3072,0x0403},
#endif
};
#else
static std::vector<Vid_pid> DeviceID{
{0x64B,0x7823},
#ifdef G200
#ifdef ISG100
{0x3072,0x100},
{0x3072,0x139},
#else
{0x3072,0x239},
{0x3072,0x200},
#endif // ISG100
#elif defined G300
{0x3072,0x0300},
#ifdef ANDROIDSERIAL
{0x3072,0x0302},
#else
{0x3072,0x0339},
#endif // ANDROIDSERIAL
#elif defined G400
{0x3072,0x0400},
#ifdef ANDROIDSERIAL
{0x3072,0x0402},
#else
{0x3072,0x0439},
#endif // ANDROIDSERIAL
#endif // ISG100
};
#endif
static void DeleteWnd(CDialog* pWnd) {
if (pWnd && pWnd->GetSafeHwnd()) {
if (pWnd->m_hWnd)
DestroyWindow(pWnd->m_hWnd);
}
}
static std::unique_ptr<CTwainUI, void(*)(CDialog*)> guiTwain(nullptr, DeleteWnd);
//static std::unique_ptr<Cmsgbox> msgbox;
#if TWPP_DETAIL_OS_WIN
static std::unique_ptr<CDialog, void(*)(CDialog*)> guiBridge(nullptr, DeleteWnd);
#endif
//static std::unique_ptr<CIndicatorDlg, void(*)(CDialog*)> guiIndicator(nullptr, DeleteWnd);
static CIndicatorDlg* guiIndicator = NULL;
//#define HG_VIRTUAL
#ifndef HG_VIRTUAL
static std::unique_ptr<IScanner> scanner; //(new GScanO200());
#else
static std::unique_ptr<IScanner> scanner(new GScanVirtual());
#endif
long __stdcall callback(EXCEPTION_POINTERS* ex)
{
if (scanner.get())
{
if (scanner->IsConnected())
scanner->Stop_scan();
}
HANDLE handle = CreateFile((FileTools::get_errorlog_path_w()+L"error.dmp").c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(!handle)
return EXCEPTION_EXECUTE_HANDLER;
MINIDUMP_EXCEPTION_INFORMATION dump;
dump.ExceptionPointers = ex;
dump.ThreadId = GetCurrentThreadId();
dump.ClientPointers = TRUE;
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), handle, MiniDumpWithFullMemory, &dump, NULL, NULL);
FatalAppExit(-1, L"TWAIN Error Exit ");
return EXCEPTION_EXECUTE_HANDLER;
}
static std::once_flag oc;
HuagaoDs::HuagaoDs()
: m_scanparam(new GScanCap)
, bmpData(new std::vector<unsigned char>)
, hMutex(NULL)
{
std::call_once(oc, [&]() {
log4cplus::Initializer();
SetUnhandledExceptionFilter(callback);
//void* addr = (void*)GetProcAddress(LoadLibrary(L"kernel32.dll"), "SetUnhandledExceptionFilter"); //<2F><>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SetUnhandledExceptionFilter<65><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ô˺<C3B4><CBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧЧ
//if (addr)
//{
// uchar code[16];
// memset(code, 0, 16);
// int size = 0;
// code[size++] = 0x33;
// code[size++] = 0xc0;
// code[size++] = 0xc2;
// code[size++] = 0x04;
// code[size++] = 0x00;
// DWORD dwoldflag, dwtempflag;
// VirtualProtect(addr, size, PAGE_READWRITE, &dwoldflag);
// WriteProcessMemory(GetCurrentProcess(), addr, code, size, NULL);
// VirtualProtect(addr, size, dwoldflag, &dwtempflag);
//}
});
//log4cplus::Initializer();
//log4cplus::deinitialize();
/*string ss1= getOSInfo();
string ss2=getManufactureID();
string ss3=getCpuType();
string ss4= getMemoryInfo();
DWORD dwNum;
CString aas[10];
GetDiskInfo(dwNum,aas);*/
//memoryinfo.reset(new std::thread([this]() {
// PROCESS_MEMORY_COUNTERS pmc;
// GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc));
// while (pmc.PeakPagefileUsage < 0x40000000&&m_memoryfalg){
// GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc));
// std::this_thread::sleep_for(std::chrono::milliseconds(10));
// }
// if (scanner.get()){
// scanner->Stop_scan();
// scanner->reset();
// scanner->ResetScanner();
// }
// //guiIndicator.reset();
// if (!m_memoryfalg)
// return;
// MessageBox(NULL, L"<22>ڴ治<DAB4><E6B2BB>", L"<22><>ʾ", MB_OK| MB_SYSTEMMODAL);
//}));
}
void HuagaoDs::showmsg(std::string caption, std::string text, int retcode)
{
if (scanner.get()) {
int num = scanner->get_imgnReaded() * (m_scanparam->is_duplex ? 2 : 1) * (m_scanparam->multi_output_red ? 2 : 1) / (m_scanparam->en_fold ? 2 : 1) * (m_scanparam->is_split ? 2 : 1)
* (m_scanparam->en_multi_output ? (m_scanparam->multioutput < 0 ? 1 : (m_scanparam->multioutput == 0 ? 3 : 2)) : 1);
int imgread = scanner->get_imgnReaded();
IScanner* ptr = scanner.get();
if (typeid(*ptr) == typeid(GScanO1003399))
{
//readnum = readnum / 2 * (m_scanparam->en_fold ? 2 : 1);
num = scanner->get_imgnReaded() * (m_scanparam->multi_output_red ? 2 : 1) * (m_scanparam->is_split ? 2 : 1) * (m_scanparam->en_multi_output ? (m_scanparam->multioutput < 0 ? 1 : (m_scanparam->multioutput == 0 ? 3 : 2)) : 1);
if(!m_scanparam->en_fold)
imgread /= 2;
}
if (retcode == 200)
{
if (!(m_scanparam->is_autodiscradblank_normal || m_scanparam->is_autodiscradblank_vince))
{
text += "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>ʹ<EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\nɨ<EFBFBD><EFBFBD>ͳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD>\n<EFBFBD><EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD>ţ<EFBFBD>--\nɨ<EFBFBD><EFBFBD>ţ<EFBFBD>" + to_string(imgread) + "\nɨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ţ<EFBFBD>--\n<EFBFBD>ϴ<EFBFBD><EFBFBD><EFBFBD>ҳ<EFBFBD><EFBFBD>"
+ to_string(scanner->get_imgTransfered()) + "\n<EFBFBD>ϴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ<EFBFBD><EFBFBD>" + to_string(num - scanner->get_imgTransfered());
scanner->set_lose_image_num(0);
}
}
else
{
if (!(m_scanparam->is_autodiscradblank_normal || m_scanparam->is_autodiscradblank_vince))
{
text += "\nɨ<EFBFBD><EFBFBD>ͳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD>\n<EFBFBD><EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD>ţ<EFBFBD>" + to_string(scanner->get_scannum()) +
"\nɨ<EFBFBD><EFBFBD>ţ<EFBFBD>" + to_string(imgread) + "\nɨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ţ<EFBFBD>" + to_string(scanner->get_scannum() - imgread) +
"\n<EFBFBD>ϴ<EFBFBD><EFBFBD><EFBFBD>ҳ<EFBFBD><EFBFBD>" + to_string(scanner->get_imgTransfered()) + "\n<EFBFBD>ϴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ<EFBFBD><EFBFBD>" + to_string(num - scanner->get_imgTransfered());
scanner->set_lose_image_num(0);
}
}
}
FileTools::kill_process(L"hidedlg.exe");
//system("taskkill /f /im hidedlg.exe");
ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString((text + " " + caption).c_str()), NULL, SW_HIDE);
}
void HuagaoDs::hgmsg(CString str)
{
ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), str, NULL, SW_HIDE);
}
HuagaoDs::~HuagaoDs()
{
if (memoryinfo.get()) {
m_memoryfalg = false;
if (memoryinfo->joinable())
memoryinfo->join();
}
if (scanner.get())
scanner.reset();
}
const Identity& HuagaoDs::defaultIdentity() noexcept {
// remember, we return a reference, therefore the identity must not be placed on the stack of this method
return srcIdent;
}
Result HuagaoDs::call(const Identity& origin, DataGroup dg, Dat dat, Msg msg, void* data) {
try {
// we can override almost anything from SourceFromThis, even the top-most source instance call
//FileTools::write_log("D:\\1.txt", "call:datagroup-"+to_string((int)dg)+"dat-"+to_string(int(dat))+"msg-"+to_string(int(msg)));
return Base::call(origin, dg, dat, msg, data);
}
catch (const CapabilityException& e) {
FileTools::writelog(log_ERROR, e.what());
return badValue();
}
}
Result HuagaoDs::customDataGet(const Twpp::Identity& origin, Twpp::CustomData& data)
{
//<2F>ӱ<EFBFBD><D3B1><EFBFBD>Ĭ<EFBFBD><C4AC><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><C3B5>ļ<EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD>ȡ<EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD>ϴ<EFBFBD>
TCHAR szIniFile[MAX_PATH] = { 0 };
SHGetSpecialFolderPath(NULL, szIniFile, CSIDL_LOCAL_APPDATA, TRUE);
_tcscat(szIniFile, HUAGAO_SCAN);
_tcscat(szIniFile, TWAIN_INIPATH);
_tcscat(szIniFile, TEXT("\\"));
_tcscat(szIniFile, TWAIN_JSON_NAME);
string path = TCHAR2STRING(szIniFile);
int t;
FILE* file = fopen(path.c_str(), "rb");
fseek(file, 0, SEEK_END);
t = ftell(file);
//data = CustomData(t);
std::string buf(t, 0);
fseek(file, 0, SEEK_SET);
fread((void*)buf.c_str(), t, 1, file);
fclose(file);
data = CustomData(t);
auto pdata = data.lock<unsigned char>();
memcpy(pdata.data(), buf.c_str(), t);
return success();
}
Result HuagaoDs::customDataSet(const Twpp::Identity& origin, Twpp::CustomData& data)
{
GScanCap sc;
//<2F><><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>תGscanCaps
GscanJsonConfig js;
std::string str;
str.resize(data.size());
auto pdata = data.lock<unsigned char>();
memcpy((void*)str.c_str(), pdata, data.size());
//vector<GScanCap> vc = js.parseJsonFromString(str);
//m_scanparam.reset(new GScanCap(vc[0]));
//std::unique_ptr<GScanCap> cap(new GScanCap(js.JsonToGscancap(json::parse(str))));
m_scanparam.reset(new GScanCap(js.JsonToGscancap(json::parse(str))));
return success();
}
// some helper functions to handle capability stuff
template<typename T>
static Result oneValGet(Msg msg, Capability& data, const T& value) {
switch (msg) {
case Msg::Get:
case Msg::GetCurrent:
case Msg::GetDefault:
data = Capability::createOneValue(data.type(), value);
return {};
default:
return { ReturnCode::Failure, ConditionCode::CapBadOperation };
}
}
static Result oneValGetString(Msg msg, Capability& data, std::string value) {
Str255 str;
str.setData(value.c_str(), value.size());
return oneValGet(msg, data, str);
}
template<typename T>
static Result enmGet(Msg msg, Capability& data, const T& value) {
switch (msg) {
case Msg::Get:
data = Capability::createEnumeration(data.type(), { value });
return {};
case Msg::GetCurrent:
case Msg::GetDefault:
data = Capability::createOneValue(data.type(), value);
return {};
default:
return { ReturnCode::Failure, ConditionCode::CapBadOperation };
}
}
template<typename T>
static Result oneValGetSet(Msg msg, Capability& data, T& value, const T& def) {
switch (msg) {
case Msg::Reset:
value = def;
// fallthrough
case Msg::Get:
case Msg::GetCurrent:
data = Capability::createOneValue(data.type(), value);
return {};
case Msg::GetDefault:
data = Capability::createOneValue(data.type(), def);
return {};
case Msg::Set:
value = data.currentItem<T>();
return {};
default:
return { ReturnCode::Failure, ConditionCode::CapBadOperation };
}
}
template<typename T>
static Result oneValGetSetConst(Msg msg, Capability& data, const T& def) {
switch (msg) {
case Msg::Get:
case Msg::GetCurrent:
case Msg::GetDefault:
case Msg::Reset:
data = Capability::createOneValue(data.type(), def);
return {};
case Msg::Set:
return data.currentItem<T>() == def ?
Result() : Result(ReturnCode::Failure, ConditionCode::BadValue);
default:
return { ReturnCode::Failure, ConditionCode::CapBadOperation };
}
}
template<typename T>
static Result enmGetSetConst(Msg msg, Capability& data, const T& def) {
switch (msg) {
case Msg::Get:
data = Capability::createEnumeration(data.type(), { def });
return {};
case Msg::GetCurrent:
case Msg::GetDefault:
case Msg::Reset:
data = Capability::createOneValue(data.type(), def);
return {};
case Msg::Set:
return data.currentItem<T>() == def ?
Result() : Result(ReturnCode::Failure, ConditionCode::BadValue);
default:
return { ReturnCode::Failure, ConditionCode::CapBadOperation };
}
}
/// Shortcut for Result(RC::Failure, CC::CheckDeviceOnline).
static constexpr Result checkDeviceOnline() noexcept {
return { ReturnCode::Failure,ConditionCode::CheckDeviceOnline };
}
Result HuagaoDs::capCommon(const Identity&, Msg msg, Capability& data) {
auto it = m_caps.find(data.type());
if (it != m_caps.end()) {
return (it->second)(msg, data);
}
return capUnsupported();
}
Result HuagaoDs::capabilityGet(const Identity& origin, Capability& data) {
return capCommon(origin, Msg::Get, data);
}
Result HuagaoDs::capabilityGetCurrent(const Identity& origin, Capability& data) {
return capCommon(origin, Msg::GetCurrent, data);
}
Result HuagaoDs::capabilityGetDefault(const Identity& origin, Capability& data) {
return capCommon(origin, Msg::GetDefault, data);
}
Result HuagaoDs::capabilityQuerySupport(const Identity&, Capability& data) {
auto it = m_query.find(data.type());
MsgSupport sup = it != m_query.end() ? it->second : msgSupportEmpty;
data = Capability::createOneValue(data.type(), sup);
return success();
}
template<typename T, Twpp::CapType cap>
Result CapSupGetAll(Msg msg, Capability& data, std::initializer_list<T> values, T& currvalue, T defaultvalue, UInt32 currindex, UInt32 defaultindex) {
switch (msg) {
case Msg::Get:
data = Capability::createEnumeration<cap>((T2)values, currindex, defaultindex);
return { ReturnCode::Success, ConditionCode::Success };
case Msg::GetCurrent:
case Msg::GetDefault:
data = Capability::createOneValue(values[defaultindex]);
return { ReturnCode::Success, ConditionCode::Success };
default:
return { ReturnCode::Failure, ConditionCode::CapBadOperation };
}
}
template<typename T1, typename T2, Twpp::CapType cap>
Result CapSupGetAll(Msg msg, Capability& data, T1& currvalue, T2 defaultvalue) {
switch (msg) {
case Msg::Get:
case Msg::GetCurrent:
case Msg::GetDefault:
data = Capability::createOneValue<cap>((T2)defaultvalue);
return { ReturnCode::Success, ConditionCode::Success };
default:
return { ReturnCode::Failure, ConditionCode::CapBadOperation };
}
}
template<typename T, Twpp::CapType cap>
Result CapSupGetAllEx(Msg msg, Capability& data, T& currvalue, T defaultvalue) {
switch (msg) {
case Msg::Get:
case Msg::GetCurrent:
case Msg::GetDefault:
data = Capability::createOneValue<T>(cap, defaultvalue);
return { ReturnCode::Success, ConditionCode::Success };
default:
return { ReturnCode::Failure, ConditionCode::CapBadOperation };
}
}
template<typename T1, typename T2, Twpp::CapType cap>
Result CapSupGetAllReset(Msg msg, Capability& data, std::initializer_list<T2> values, T1& currvalue, T2 defaultvalue, UInt32 currindex, UInt32 defaultindex) {
switch (msg) {
case Msg::Get:
data = Capability::createEnumeration<cap>(values, currindex, defaultindex);
return { ReturnCode::Success, ConditionCode::Success };
case Msg::GetCurrent:
data = Capability::createOneValue<cap>((T2)currvalue);
return { ReturnCode::Success, ConditionCode::Success };
case Msg::Reset:
case Msg::GetDefault:
currvalue = (T1)defaultvalue;
data = Capability::createOneValue<cap>(defaultvalue);
return { ReturnCode::Success, ConditionCode::Success };
default:
return { ReturnCode::Failure, ConditionCode::CapBadOperation };
}
}
template<typename T1, typename T2, Twpp::CapType cap>
Result CapSupGetAllReset(Msg msg, Capability& data, T1& currvalue, T2 defaultvalue) {
switch (msg) {
case Msg::Get:
case Msg::GetCurrent:
data = Capability::createOneValue<cap>((T2)currvalue);
return { ReturnCode::Success, ConditionCode::Success };
case Msg::Reset:
case Msg::GetDefault:
currvalue = (T1)defaultvalue;
data = Capability::createOneValue<cap>(defaultvalue);
return { ReturnCode::Success, ConditionCode::Success };
default:
return { ReturnCode::Failure, ConditionCode::CapBadOperation };
}
}
template<typename T1, typename T2, Twpp::CapType cap>
Result CapSupGetAllResetEx(Msg msg, Capability& data, std::initializer_list<T2> values, T1& currvalue, T2 defaultvalue, UInt32 currindex, UInt32 defaultindex) {
switch (msg) {
case Msg::Get:
data = Capability::createEnumeration<T2>(cap, values, currindex, defaultindex);
return { ReturnCode::Success, ConditionCode::Success };
case Msg::GetCurrent:
data = Capability::createOneValue<T2>(cap, (T2)currvalue);
return { ReturnCode::Success, ConditionCode::Success };
case Msg::Reset:
case Msg::GetDefault:
currvalue = (T1)defaultvalue;
data = Capability::createOneValue<T2>(cap, defaultvalue);
return { ReturnCode::Success, ConditionCode::Success };
default:
return { ReturnCode::Failure, ConditionCode::CapBadOperation };
}
}
template<typename T1, typename T2, Twpp::CapType cap>
Result CapSupGetAllResetEx(Msg msg, Capability& data, T1& currvalue, T2 defaultvalue) {
switch (msg) {
case Msg::Get:
case Msg::GetCurrent:
data = Capability::createOneValue<T2>(cap, (T2)currvalue);
return { ReturnCode::Success, ConditionCode::Success };
case Msg::Reset:
case Msg::GetDefault:
currvalue = (T1)defaultvalue;
data = Capability::createOneValue<T2>(cap, defaultvalue);
return { ReturnCode::Success, ConditionCode::Success };
default:
return { ReturnCode::Failure, ConditionCode::CapBadOperation };
}
}
Result HuagaoDs::capabilityReset(const Identity& origin, Capability& data) {
return capCommon(origin, Msg::Reset, data);
}
Result HuagaoDs::capabilityResetAll(const Identity& origin) {
for (auto& pair : m_query) {
if ((pair.second & MsgSupport::Reset) != msgSupportEmpty) {
Capability dummyCap(pair.first);
capCommon(origin, Msg::Reset, dummyCap);
}
}
return success();
}
Result HuagaoDs::capabilitySet(const Identity& origin, Capability& data) {
return capCommon(origin, Msg::Set, data);
}
Result HuagaoDs::eventProcess(const Identity&, Event& event) {
// Qt needs to process its events, otherwise the GUI will appear frozen
// this is Windows-only method, Linux and macOS behave differently
//FileTools::writelog(log_ERROR, "eventProcess " + to_string((int)event.message()));
if (guiTwain) {
// // QApplication::processEvents(); - TODO: needs more investigation; results in freeze when attempting to scan using old DSM
// QApplication::sendPostedEvents();
//guiTwain->PostMessageW((UINT)(event.message()));
guiTwain->SendMessage((UINT)(event.message()));
}
//if (inState(DsState::XferReady))
// event.setMessage(Msg::XferReady);
//else
event.setMessage(Msg::Null);
return { ReturnCode::NotDsEvent, ConditionCode::Success };
}
Twpp::Result HuagaoDs::deviceEventGet(const Twpp::Identity& origin, Twpp::DeviceEvent& data)
{
if (devEvent.size() > 0)
{
data = devEvent.front();
devEvent.pop();
return success();
}
return seqError();
}
//add------------------<2D><><EFBFBD><EFBFBD>jpgͼ<67><CDBC>dpi---------------------------
void HuagaoDs::SetResoluton(const char* path, int resolution)
{
FILE* file = fopen(path, "rb+");
if (!file)
return;
//<2F><>ȡ<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>С
int len = _filelength(_fileno(file));
char* buf = new char[len];
fread(buf, sizeof(char), len, file);
char* pResolution = (char*)&resolution;
//<2F><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>ͼƬ<CDBC>ܶȵ<DCB6>λ
buf[0x0D] = 1;
//ˮƽ<CBAE>ܶȣ<DCB6>ˮƽ<CBAE>ֱ<EFBFBD><D6B1><EFBFBD>
buf[0x0E] = pResolution[1];
buf[0x0F] = pResolution[0];
//<2F><>ֱ<EFBFBD>ܶȣ<DCB6><C8A3><EFBFBD>ֱ<EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD>
buf[0x10] = pResolution[1];
buf[0x11] = pResolution[0];
fseek(file, 0, SEEK_SET);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭʼ<D4AD><CABC><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD>޸<EFBFBD><DEB8><EFBFBD>Ч
fwrite(buf, sizeof(char), len, file);
fclose(file);
delete[]buf;
}
void HuagaoDs::dogear_callback(int indexpaper)
{
CString text;
text.Format(_T("74 %d"), indexpaper);
//ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), text, NULL, SW_HIDE);
showmsg("<EFBFBD><EFBFBD>ʾ","<EFBFBD><EFBFBD>"+to_string(indexpaper)+"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>۽ǣ<EFBFBD>");
scanner->Stop_scan();
//scanner->reset();
scanner->ResetScanner();
onDeviceEvent(DOG_EAR);
}
Result HuagaoDs::identityOpenDs(const Identity& origin) {
#ifdef G400
hMutex = CreateMutex(NULL, FALSE, _T("LookitApp_4"));
#elif defined G300
hMutex = CreateMutex(NULL, FALSE, _T("LookitApp_3"));
#elif defined ISG100
hMutex = CreateMutex(NULL, FALSE, _T("LookitApp_1"));
#else
hMutex = CreateMutex(NULL, FALSE, _T("LookitApp_2"));
#endif // G400
if (GetLastError() == ERROR_ALREADY_EXISTS) { //<2F><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD>Mutex<65><78><EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
CloseHandle(hMutex);
hMutex = NULL;
//ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString("202"), NULL, SW_HIDE);
showmsg("<EFBFBD><EFBFBD>ʾ", msgs[(UsbSupported)202]);
return { ReturnCode::Failure, ConditionCode::CapBadOperation };
}
Twain_config().GetOrSetPintfCapability(is_printfcapability, true);
auto usblist = UsbScan_List::find_all_usb();
if (!usblist.empty())
{
for each (auto & usb in usblist)
{
for(int x=0;x<DeviceID.size();x++)
{
if (DeviceID[x].vid ==usb.vid && DeviceID[x].pid ==usb.pid)
{
vid = usb.vid;
pid = usb.pid;
if (!scanner.get()) {
#ifdef G200
if (pid == 0x139 || pid == 0x239 || pid == 0x8739 || pid == 0x8629 || pid == 0x130 ||pid == 0x8000 || pid == 0x9000 ||
pid == 0x138 || pid == 0x238 || pid == 0x2100)
scanner.reset(new GScanO1003399());
else
scanner.reset(new GScanO200());
#else
if (pid == 0x339 || pid == 0x439 || pid == 0x7039 || pid == 0x8529 || pid == 0x8429)
scanner.reset(new GScanO1003399());
else {
#ifdef ANDROIDSERIAL
if (pid == 0x402 || pid == 0x302 || pid == 0x7002)
scanner.reset(new GScan439Android());
else
scanner.reset(new GScanO400Android());
#else
scanner.reset(new GScanO400());
#endif
}
#endif // G400
break;
}
}
}
}
}
FileTools::writelog(log_INFO, "open ds find device vid=" + to_string(vid) + "\tpid=" + to_string(pid));
if (vid == 0 || pid == 0)
{
//ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString("201"), NULL, SW_HIDE);
//showmsg("<22><>ʾ", msgs[(UsbSupported)201]);
ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString("δ<EFBFBD>ҵ<EFBFBD>ɨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>!<21><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD>USB<53><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>ͨ! <20><>ʾ"), NULL, SW_HIDE);
if (hMutex) {
CloseHandle(hMutex);
hMutex = NULL;
}
return checkDeviceOnline();
}
scanner->open(vid, pid);
if (scanner->get_ErrorCode() == SLEEPING) {
if (hMutex) {
ReleaseMutex(hMutex);
CloseHandle(hMutex);
hMutex = NULL;
}
return seqError();
}
if (!scanner->IsConnected()) {
//ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString("201"), NULL, SW_HIDE);
showmsg("<EFBFBD><EFBFBD>ʾ", msgs[(UsbSupported)201]);
if (hMutex) {
CloseHandle(hMutex);
hMutex = NULL;
}
return checkDeviceOnline();
}
else
{
scanner->regist_deviceevent_callback(DeviceEvent_callback, this);
auto dgcall = [&](int pagenum)
{
//ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), text, NULL, SW_HIDE);
showmsg("<EFBFBD><EFBFBD>ʾ", "<EFBFBD><EFBFBD>" + to_string(pagenum) + "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>۽ǣ<EFBFBD>");
scanner->Stop_scan();
//scanner->reset();
scanner->ResetScanner();
onDeviceEvent(DOG_EAR);
};
scanner->DogEar_callback(dgcall);
}
m_haveError = false;
updataGscanCap();
bmpData->resize(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));
BITMAPINFOHEADER& bmInfo = *((BITMAPINFOHEADER*)header());
bmInfo.biHeight = 2000;
bmInfo.biWidth = 2000;
bmInfo.biBitCount = m_scanparam->pixtype == 2 ? 24 : (m_scanparam->pixtype == 1 ? 8 : 1);
m_iBitdepth = m_scanparam->pixtype == 2 ? 24 : (m_scanparam->pixtype == 1 ? 8 : 1);
//MessageBox(NULL, L"2", L"", 0);
// init caps
// there are caps a minimal source must support
// query -> says which operations a cap supports
// caps -> has handler for each specific cap
m_query[CapType::SupportedCaps] = msgSupportGetAll;
m_caps[CapType::SupportedCaps] = [this](Msg msg, Capability& data) {
if ((msg == Msg::Get) || (Msg::GetCurrent == msg) || (Msg::GetDefault == msg)) {
data = Capability::createArray<CapType::SupportedCaps>(m_caps.size());
auto arr = data.array<CapType::SupportedCaps>();
UInt32 i = 0;
for (const auto& kv : m_caps) {
arr[i] = kv.first;
i++;
}
return success();
}
else
return capBadOperation();
};
m_query[CapType::UiControllable] = msgSupportGetAll;
m_caps[CapType::UiControllable] = std::bind(oneValGet<Bool>, _1, _2, Bool(true));
m_query[CapType::DeviceOnline] = msgSupportGetAll;
//m_caps[CapType::DeviceOnline] = std::bind(enmGet<Bool>, _1, _2, Bool(scanner->IsConnected()));
m_caps[CapType::DeviceOnline] = [this](Msg msg, Capability& data) -> Result {
CapabilityPrintf(msg, enum2str(CapType::DeviceOnline));
switch (msg) {
case Msg::Get:
case Msg::GetCurrent:
case Msg::GetDefault:
data = Capability::createOneValue<CapType::DeviceOnline>((Twpp::Bool)scanner->IsConnected());
return {};
default:
return { ReturnCode::Failure, ConditionCode::CapBadOperation };
}
};
m_query[CapType::XferCount] = msgSupportGetAllSetReset;
m_caps[CapType::XferCount] = [this](Msg msg, Capability& data) -> Result {
CapabilityPrintf(msg, enum2str(CapType::XferCount),msg==Msg::Set?to_string((int)data.currentItem<Int16>()):"");
if (msg == Msg::Set) {
auto item = data.currentItem<Int16>();
if (item > 65535 || item < -1 || item == 0) {
return badValue();
}
m_scanparam->scannum = item;
return success();
}
Int16 tmp_count = m_scanparam->scannum;
auto ret = oneValGetSet<Int16>(msg, data, tmp_count, -1);
if (!Twpp::success(ret) && m_scanparam->scannum == 0) {
m_scanparam->scannum = -1;
return { ReturnCode::CheckStatus, ConditionCode::BadValue };
}
return ret;
};
m_query[CapType::ICompression] = msgSupportGetAllSetReset;
//m_caps[CapType::ICompression] = std::bind(enmGetSetConst<Compression>, _1, _2, Compression::None);
m_caps[CapType::ICompression] = [this](Msg msg, Capability& data)->Result{
CapabilityPrintf(msg, enum2str(CapType::ICompression), msg == Msg::Set ? to_string((int)data.currentItem<CapType::ICompression>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::ICompression>();
if (Compression::None == mech || mech == Compression::Group4) {
if (mech == Compression::Group4)
{
if (m_scanparam->pixtype != 0)
return badValue();
}
m_compression = mech;
return success();
}
else
return badValue();
}
return CapSupGetAllReset<Compression, Compression, CapType::ICompression>(msg, data, { Compression::None, Compression::Group4 }, m_compression, Compression::None, m_compression == Compression::None ? 0 : 1, 0);
};
m_query[CapType::IBitDepth] = msgSupportGetAllSetReset;
m_caps[CapType::IBitDepth] = [this](Msg msg, Capability& data) -> Result {
CapabilityPrintf(msg, enum2str(CapType::IBitDepth), msg == Msg::Set ? to_string((int)data.currentItem<CapType::IBitDepth>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::IBitDepth>();
if (((mech == 1) && (m_scanparam->pixtype == 0)) || ((mech == 8) && (m_scanparam->pixtype == 1)) || ((mech == 24) && (m_scanparam->pixtype == 2))) {
m_iBitdepth = (UINT16)mech;
return success();
}
return badValue();
}
return CapSupGetAllReset<UINT16, UINT16, CapType::IBitDepth>(msg, data, m_iBitdepth, 24);
};
m_query[CapType::IBitOrder] = msgSupportGetAllSetReset;
m_caps[CapType::IBitOrder] = std::bind(oneValGetSetConst<BitOrder>, _1, _2, BitOrder::MsbFirst);
m_query[CapType::IPlanarChunky] = msgSupportGetAllSetReset;
m_caps[CapType::IPlanarChunky] = std::bind(enmGetSetConst<PlanarChunky>, _1, _2, PlanarChunky::Chunky);
m_query[CapType::IPhysicalWidth] = msgSupportGetAll;
m_caps[CapType::IPhysicalWidth] = std::bind(oneValGet<Fix32>, _1, _2, Fix32(static_cast<float>(header()->biWidth) / m_scanparam->resolution_dst));
m_query[CapType::IPhysicalHeight] = msgSupportGetAll;
m_caps[CapType::IPhysicalHeight] = std::bind(oneValGet<Fix32>, _1, _2, Fix32(static_cast<float>(header()->biHeight) / m_scanparam->resolution_dst));
m_query[CapType::IPixelFlavor] = msgSupportGetAllSetReset;
m_caps[CapType::IPixelFlavor] = std::bind(enmGetSetConst<PixelFlavor>, _1, _2, PixelFlavor::Chocolate);
m_query[CapType::IPixelType] = msgSupportGetAllSetReset;
m_caps[CapType::IPixelType] = [this](Msg msg, Capability& data) -> Result {
CapabilityPrintf(msg, enum2str(CapType::IPixelType), msg == Msg::Set ? to_string((int)data.currentItem<CapType::IPixelType>()) : "");
if( Msg::Set==msg) {
auto mech = data.currentItem<CapType::IPixelType>();
if (mech == PixelType::Rgb || mech == PixelType::Gray || mech == PixelType::BlackWhite)
{
m_scanparam->automaticcolor = FALSE;
m_scanparam->pixtype = (int)mech;
if (m_scanparam->pixtype == (int)PixelType::Rgb){
m_scanparam->filter = (BYTE)Filter::None;
m_scanparam->enhance_color = (BYTE)Enchace_Color::Enhance_None;
}
else{
m_scanparam->multi_output_red = 0;//<2F>Dz<EFBFBD>ɫģʽ<C4A3><EFBFBD><C2B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
m_scanparam->detachnoise.is_detachnoise = false;
m_scanparam->fadeback = false;
m_scanparam->hsvFilter = 0;
m_scanparam->hsvcorrect = 0;
//if (mech == PixelType::BlackWhite)
//{
// if (m_scanparam->filter == (uint8)Filter::None && m_scanparam->enhance_color == Enchace_Color::Enhance_None)
// {
// m_scanparam->enhance_color = 1;
// }
//}
}
m_iBitdepth = mech == PixelType::Rgb ? 24 : (mech == PixelType::Gray ? 8 : 1);
return success();
}
return badValue();
}
return CapSupGetAllReset<int, PixelType, CapType::IPixelType>(msg, data, { PixelType::BlackWhite,PixelType::Gray,PixelType::Rgb }, m_scanparam->pixtype, PixelType::Rgb,
m_scanparam->pixtype == (int)PixelType::Rgb ? 2 : (m_scanparam->pixtype == (int)PixelType::Gray ? 1 : 0), 2);
};
m_query[CapType::IAutomaticColorEnabled] = msgSupportGetAllSetReset;
m_caps[CapType::IAutomaticColorEnabled] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapType::IAutomaticColorEnabled), msg == Msg::Set ? to_string((int)data.currentItem<CapType::IAutomaticColorEnabled>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::IAutomaticColorEnabled>();
if (mech) {
m_scanparam->automaticcolor = TRUE;
m_scanparam->filter = (BYTE)Filter::None;
m_scanparam->enhance_color = (BYTE)Enchace_Color::Enhance_None;
m_scanparam->pixtype = (int)PixelType::Rgb;
}
else
m_scanparam->automaticcolor = FALSE;
m_iBitdepth = m_scanparam->pixtype == int(PixelType::Rgb) ? 24 : (m_scanparam->pixtype == int(PixelType::Gray) ? 8 : 1);
return success();
}
return CapSupGetAllReset<int, Bool, CapType::IAutomaticColorEnabled>(msg, data, { FALSE,TRUE }, m_scanparam->automaticcolor, false, m_scanparam->automaticcolor ? 1 : 0, 0);
};
m_query[CapType::IAutomaticColorNonColorPixelType] = msgSupportGetAllSetReset;
m_caps[CapType::IAutomaticColorNonColorPixelType] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapType::IAutomaticColorNonColorPixelType), msg == Msg::Set ? to_string((int)data.currentItem<CapType::IAutomaticColorNonColorPixelType>()) : "");
if (msg == Msg::Set) {
auto mech = data.currentItem<CapType::IAutomaticColorNonColorPixelType>();
if (m_scanparam->automaticcolor == TRUE) {
if ((UInt16)mech == 0 || (UInt16)mech == 1) {
m_scanparam->automaticcolortype = (UInt16)mech;
return success();
}
}
return seqError();
}
return CapSupGetAllReset<int, PixelType, CapType::IAutomaticColorNonColorPixelType>(msg, data, { PixelType::BlackWhite, PixelType::Gray }, m_scanparam->automaticcolortype, PixelType::Gray, m_scanparam->automaticcolortype, 1);
};
//add------------------jpeg<65><67><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>---------------------
m_query[CapType::IJpegQuality] = msgSupportGetAllSetReset;
m_caps[CapType::IJpegQuality] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapType::IJpegQuality), msg == Msg::Set ? to_string((int)data.currentItem<CapType::IJpegQuality>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::IJpegQuality>();
if ((int)mech < 0 || (int)mech > 100)
return badValue();
m_jpegQuality = (int)mech;
return success();
}
return CapSupGetAllResetEx<unsigned short, UInt16, CapType::IJpegQuality>(msg, data, m_jpegQuality, 80);
};
m_query[CapType::IUnits] = msgSupportGetAllSetReset;
m_caps[CapType::IUnits] = std::bind(enmGetSetConst<Unit>, _1, _2, Unit::Inches);
m_query[CapType::IXferMech] = msgSupportGetAllSetReset;
m_caps[CapType::IXferMech] = [this](Msg msg, Capability& data) -> Result {
CapabilityPrintf(msg, enum2str(CapType::IXferMech), msg == Msg::Set ? to_string((int)data.currentItem<CapType::IXferMech>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::IXferMech>();
if (mech == XferMech::Native || mech == XferMech::Memory || mech == XferMech::File) {
m_capXferMech = mech;
return success();
}
else {
return badValue();
}
}
return CapSupGetAllReset<XferMech, XferMech, CapType::IXferMech>(msg, data, { XferMech::Native, XferMech::File, XferMech::Memory }, m_capXferMech, XferMech::Native, (int)m_capXferMech, 0);
};
m_query[CapType::IXResolution] = msgSupportGetAllSetReset;
m_caps[CapType::IXResolution] = [this](Msg msg, Capability& data) {
CapabilityPrintf(msg, enum2str(CapType::IXResolution), msg == Msg::Set ? to_string((float)data.currentItem<CapType::IXResolution>()) : "");
switch (msg) {
case Msg::Get:
data = Capability::createRange<CapType::IXResolution>(Fix32(100.0f), Fix32(600.0f), Fix32(1.0f), Fix32(m_scanparam->resolution_dst), Fix32(200.0));
return success();
case Msg::GetCurrent:
data = Capability::createOneValue<CapType::IXResolution>(Fix32(m_scanparam->resolution_dst));
return success();
case Msg::GetDefault:
case Msg::Reset:
m_scanparam->resolution_dst = 200.0f;
data = Capability::createOneValue<CapType::IXResolution>(Fix32(200.0f));
return success();
case Msg::Set: {
auto mech = data.currentItem<CapType::IXResolution>();
if (mech < 100.0f || mech > 600.0f)
return badValue();
m_scanparam->resolution_dst = (float)mech;
return success();
}
default:
return capBadOperation();
}
};
m_query[CapType::IYResolution] = msgSupportGetAllSetReset;
m_caps[CapType::IYResolution] = m_caps[CapType::IXResolution];
m_query[CapType::IXNativeResolution] = msgSupportGetAll;
m_caps[CapType::IXNativeResolution] = std::bind(enmGet<Fix32>, _1, _2, Fix32(200.0));
m_query[CapType::IYNativeResolution] = msgSupportGetAll;
m_caps[CapType::IYNativeResolution] = m_caps[CapType::IXNativeResolution];
m_query[CapType::ISupportedSizes] = msgSupportGetAllSetReset;
m_caps[CapType::ISupportedSizes] = [this](Msg msg, Capability& data) {
CapabilityPrintf(msg, enum2str(CapType::ISupportedSizes), msg == Msg::Set ? to_string((int)data.currentItem<UInt16>()) : "");
if (Msg::Set == msg) {
//if (m_scanparam->is_autocrop)
// return success();
auto paper = data.currentItem<UInt16>();
if (std::distance(paperSizeList.begin(), std::find(paperSizeList.begin(), paperSizeList.end(), paper)) == paperSizeList.size())
return badValue();
else {
m_scanparam->papertype = (BYTE)paper;
if (paper == (BYTE)PaperSize::None || paper == (BYTE)PaperSize::UsStatement) {
m_scanparam->paperAlign = PaperAlign::Rot0;
m_scanparam->en_sizecheck = 0;
m_scanparam->en_fixedpaper = 0;
}
if (paper == (BYTE)PaperSize::UsStatement) {
m_autosize = (UInt16)AutoSize::None;
m_autoboarderdetcet = false;
m_scanparam->is_autocrop = 0;
}
else {
m_autosize = (paper == (BYTE)PaperSize::None) ? (UInt16)AutoSize::Auto : (UInt16)AutoSize::None;
m_autoboarderdetcet = paper == (BYTE)PaperSize::None;
m_scanparam->is_autocrop = paper == (BYTE)PaperSize::None ? 1 : 0;
}
return success();
}
}
return CapSupGetAllReset<BYTE, PaperSize, CapType::ISupportedSizes>(msg, data, { PaperSize::A4,PaperSize::A5,PaperSize::A6,
PaperSize::IsoB5,PaperSize::IsoB6,PaperSize::UsLetter,
PaperSize::UsLegal,PaperSize::None,(PaperSize)PaperSizeEx::K16
#ifndef G300
#if defined G200
,PaperSize::A3,PaperSize::UsLedger,PaperSize::IsoB4,
PaperSize::MaxSize,PaperSize::UsStatement,(PaperSize)PaperSizeEx::K8,(PaperSize)PaperSizeEx::K16,(PaperSize)PaperSizeEx::Trigeminy
#elif defined G400
,PaperSize::A3,PaperSize::UsLedger,PaperSize::IsoB4,PaperSize::MaxSize,PaperSize::UsStatement,
(PaperSize)PaperSizeEx::K8,(PaperSize)PaperSizeEx::K16,(PaperSize)PaperSizeEx::Trigeminy
#endif
#endif //
}, m_scanparam->papertype, PaperSize::None,
std::distance(paperSizeList.begin(), std::find(paperSizeList.begin(), paperSizeList.end(), m_scanparam->papertype)) == paperSizeList.size() ? 0 : std::distance(paperSizeList.begin(),
std::find(paperSizeList.begin(), paperSizeList.end(), m_scanparam->papertype)),
std::distance(paperSizeList.begin(), std::find(paperSizeList.begin(), paperSizeList.end(), 0)));
};
#ifdef G200
m_query[(CapType)(CapTypeEx::TwEx_SizeDetect)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_SizeDetect)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_SizeDetect), msg == Msg::Set ? to_string((int)data.currentItem<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
if (mech) {
if (m_scanparam->papertype == (uint8_t)PaperSize::None || m_scanparam->papertype == (uint8_t)PaperSize::MaxSize || m_scanparam->papertype == (uint8_t)PaperSize::UsStatement ||
m_scanparam->papertype == (uint8_t)PaperSizeEx::Trigeminy)
return badValue();
}
m_scanparam->en_sizecheck = mech;
return success();
}
return CapSupGetAllResetEx<BYTE, Bool, CapType(CapTypeEx::TwEx_SizeDetect)>(msg, data, { FALSE,TRUE }, m_scanparam->en_sizecheck, false, m_scanparam->en_sizecheck, 0);
};
//<2F><><EFBFBD><EFBFBD>cis<69>̼<EFBFBD><CCBC><EFBFBD><EFBFBD><EFBFBD>ɨ<EFBFBD><C9A8>
m_query[(CapType)(CapTypeEx::TwEx_IFixedPaper)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_IFixedPaper)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IFixedPaper), msg == Msg::Set ? to_string((int)data.currentItem<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
if (mech) {
if (m_scanparam->papertype == (uint8_t)PaperSize::None || m_scanparam->papertype == (uint8_t)PaperSize::MaxSize || m_scanparam->papertype == (uint8_t)PaperSize::UsStatement ||
m_scanparam->papertype == (uint8_t)PaperSizeEx::Trigeminy)
return badValue();
}
m_scanparam->en_fixedpaper = mech;
return success();
}
return CapSupGetAllResetEx<bool, Bool, CapType(CapTypeEx::TwEx_IFixedPaper)>(msg, data, { false,true }, m_scanparam->en_fixedpaper, false, m_scanparam->en_fixedpaper, 0);
};
#endif // G200
m_query[CapType::IOrientation] = msgSupportGetAllSetReset;
m_caps[CapType::IOrientation] = [this](Msg msg, Capability& data) -> Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::IOrientation), msg == Msg::Set ? to_string((int)data.currentItem<CapType::IOrientation>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::IOrientation>();
if ((mech == Orientation::Landscape) && (m_scanparam->papertype == (uint8_t)PaperSize::None || m_scanparam->papertype == (uint8_t)PaperSize::MaxSize ||
m_scanparam->papertype == (uint8_t)PaperSize::UsStatement || m_scanparam->papertype == (uint8_t)PaperSizeEx::Trigeminy || m_scanparam->papertype == (uint8_t)PaperSize::A3 ||
m_scanparam->papertype == (uint8_t)PaperSize::IsoB4 || m_scanparam->papertype == (uint8_t)PaperSizeEx::K8 || m_scanparam->papertype == (uint8_t)PaperSize::UsLedger))
return badValue();
if (mech == Orientation::Landscape || mech == Orientation::Portrait) {
m_scanparam->paperAlign = (PaperAlign)mech;
return success();
}
return badValue();
}
return CapSupGetAllReset<PaperAlign, Orientation, CapType::IOrientation>(msg, data, { Orientation::Portrait, Orientation::Landscape }, m_scanparam->paperAlign, Orientation::Portrait, m_scanparam->paperAlign == 0 ? 0 : 1, 0);
};
m_query[CapType::IRotation] = msgSupportGetAllSetReset;
m_caps[CapType::IRotation] = [this](Msg msg, Capability& data) -> Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::IRotation), msg == Msg::Set ? to_string((float)data.currentItem<Fix32>()) : "");
if (Msg::Set == msg) {
auto res = data.currentItem<Fix32>();
if (std::distance(imageRotateList.begin(), std::find(imageRotateList.begin(), imageRotateList.end(), res)) == imageRotateList.size())
return badValue();
else {
m_scanparam->imageRotateDegree = (float)res;
if (res != 0.0f)
m_scanparam->is_autotext = 0;
return success();
}
}
return CapSupGetAllReset<float, Fix32, CapType::IRotation>(msg, data, { Fix32(0.0f),Fix32(90.0f),Fix32(180.0f),Fix32(270.0f) }, m_scanparam->imageRotateDegree, Fix32(0.0),
std::distance(imageRotateList.begin(), std::find(imageRotateList.begin(), imageRotateList.end(), m_scanparam->imageRotateDegree)), 0);
};
#ifndef G200
scanner->Get_Scanner_PaperOn(); //<2F><><EFBFBD><EFBFBD>G300 G400 USBͨ<42>ŵ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD>޷<EFBFBD>read_bulk <20>𵽼<EFBFBD><F0B5BDBC><EFBFBD>USB<53><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#endif // !G200
m_query[CapType::SerialNumber] = msgSupportGetAll;
//m_caps[CapType::SerialNumber] = std::bind(oneValGetString, _1, _2, scanner->GetSerialNum());
m_caps[CapType::SerialNumber] = [this](Msg msg, Capability& data)->Result {
Str255 str;
str.setData(scanner->GetSerialNum().c_str(), scanner->GetSerialNum().size());
return CapSupGetAll<Str255, Str255, CapType::SerialNumber>(msg, data, str, str);
};
m_query[(CapType)(CapTypeEx::TwEx_HardwareVersion)] = msgSupportGetAll;
//m_caps[(CapType)(CapTypeEx::TwEx_HardwareVersion)] = std::bind(oneValGetString, _1, _2, scanner->GetFWVersion());
m_caps[(CapType)(CapTypeEx::TwEx_HardwareVersion)] = [this](Msg msg, Capability& data)->Result {
Str255 str;
str.setData(scanner->GetFWVersion().c_str(), scanner->GetFWVersion().size());
return CapSupGetAllEx<Str255, (CapType)CapTypeEx::TwEx_HardwareVersion>(msg, data, str, str);
};
m_query[(CapType)(CapTypeEx::TwEx_ENCODE)] = msgSupportGetAll;
//m_caps[(CapType)(CapTypeEx::TwEx_HardwareVersion)] = std::bind(oneValGetString, _1, _2, scanner->GetFWVersion());
m_caps[(CapType)(CapTypeEx::TwEx_ENCODE)] = [this](Msg msg, Capability& data)->Result {
Str255 str;
str.setData(scanner->get_scannercode().c_str(), 32);
return CapSupGetAllEx<Str255, (CapType)CapTypeEx::TwEx_ENCODE>(msg, data, str, str);
};
m_query[CapType(CapTypeEx::TwEx_SETTOKEN)] = MsgSupport::Set;
m_caps[CapType(CapTypeEx::TwEx_SETTOKEN)] = [this](Msg msg, Capability& data) -> Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::SETTOKEN));
if (msg != Msg::Set)
{
Str32 str;
str.setData("This operation is not supported ", 32);
data = Capability::createOneValue<Str32>(CapType(CapTypeEx::TwEx_SETTOKEN), str);
return success();
}
auto str = data.currentItem<Str32>();
if(str.size()!=32)
return { ReturnCode::Failure, ConditionCode::CapBadOperation };
//MessageBox(NULL, L"<22>ڴ治<DAB4><E6B2BB>", L"", MB_OK | MB_SYSTEMMODAL);
scanner->set_token(std::string(str.data()));
return success();
//return CapSupGetAll<Bool, Bool, CapType::FeederLoaded>(msg, data, Bool(scanner->Get_Scanner_PaperOn()), Bool(scanner->Get_Scanner_PaperOn()));
};
m_query[CapType::FeederLoaded] = msgSupportGetAll;
m_caps[CapType::FeederLoaded] = [this](Msg msg, Capability& data) -> Result {
CapabilityPrintf(msg, enum2str(CapType::FeederLoaded));
return CapSupGetAll<Bool, Bool, CapType::FeederLoaded>(msg, data, Bool(scanner->Get_Scanner_PaperOn()), Bool(scanner->Get_Scanner_PaperOn()));
};
m_query[CapType::Indicators] = msgSupportGetAllSetReset;
m_caps[CapType::Indicators] = [this](Msg msg, Capability& data) -> Result {
CapabilityPrintf(msg, enum2str(CapType::Indicators), msg == Msg::Set ? to_string((int)data.currentItem<CapType::Indicators>()) : "");
if (Msg::Set == msg) {
auto show = data.currentItem<CapType::Indicators>();
m_bIndicator = show;
return success();
}
return CapSupGetAllReset<bool, Bool, CapType::Indicators>(msg, data, { FALSE,TRUE }, m_bIndicator, TRUE, m_bIndicator ? 1 : 0, 1);
};
m_query[CapType::CustomDsData] = msgSupportGetAll;
m_caps[CapType::CustomDsData] = [this](Msg msg, Capability& data) -> Result {
return CapSupGetAllEx<Bool, CapType::CustomDsData>(msg, data, Bool(true), Bool(true));
};
m_query[CapType::EnableDsUiOnly] = msgSupportGetAll;
m_caps[CapType::EnableDsUiOnly] = std::bind(enmGet<Bool>, _1, _2, Bool(true));
m_query[CapType::PaperDetectable] = msgSupportGetAll;
m_caps[CapType::PaperDetectable] = std::bind(oneValGet<Bool>, _1, _2, Bool(true));
m_query[CapType::FeederEnabled] = msgSupportGetAllSetReset;
m_caps[CapType::FeederEnabled] = [this](Msg msg, Capability& data) -> Result {
CapabilityPrintf(msg, enum2str(CapType::FeederEnabled), msg == Msg::Set ? to_string((int)data.currentItem<CapType::FeederEnabled>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::FeederEnabled>();
m_bFeederEnabled = mech;
return success();
}
return CapSupGetAllReset<bool, Bool, CapType::PaperDetectable>(msg, data, m_bFeederEnabled, Bool(true));
};
m_query[CapType::Duplex] = msgSupportGetAll;
m_caps[CapType::Duplex] = std::bind(oneValGet<Duplex>, _1, _2, Duplex::OnePass);
m_query[CapType::DuplexEnabled] = msgSupportGetAllSetReset;
m_caps[CapType::DuplexEnabled] = [this](Msg msg, Capability& data) -> Result {
CapabilityPrintf(msg, enum2str(CapType::DuplexEnabled), msg == Msg::Set ? to_string((int)data.currentItem<CapType::DuplexEnabled>()) : "");
if (Msg::Set == msg) {
bool mech = data.currentItem<CapType::DuplexEnabled>();
m_scanparam->is_duplex = mech;
if (!mech){
m_scanparam->is_backrotate180 = 0;//<2F><><EFBFBD><EFBFBD><E6B1B3><EFBFBD><EFBFBD>ת180<38><EFBFBD><E3B2BB><EFBFBD><EFBFBD>
m_scanparam->is_switchfrontback = 0;
m_scanparam->is_autodiscradblank_normal = m_scanparam->is_autodiscradblank_vince = m_scanparam->en_fold = 0;
}
return success();
}
return CapSupGetAllReset<BYTE, Bool, CapType::DuplexEnabled>(msg, data, m_scanparam->is_duplex, Bool(true));
};
m_query[CapType::AutoFeed] = msgSupportGetAllSetReset;
m_caps[CapType::AutoFeed] = [this](Msg msg, Capability& data) -> Result {
CapabilityPrintf(msg, enum2str(CapType::AutoFeed), msg == Msg::Set ? to_string((int)data.currentItem<CapType::AutoFeed>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::AutoFeed>();
m_bAutoFeed = mech;
return success();
}
return CapSupGetAllReset<bool, Bool, CapType::AutoFeed>(msg, data, { false,true }, m_bAutoFeed, true, m_bAutoFeed ? 1 : 0, 1);
};
m_query[CapType::IImageFileFormat] = msgSupportGetAllSetReset;
m_caps[CapType::IImageFileFormat] = [this](Msg msg, Capability& data) -> Result {
CapabilityPrintf(msg, enum2str(CapType::IImageFileFormat), msg == Msg::Set ? to_string((int)data.currentItem<CapType::IImageFileFormat>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::IImageFileFormat>();
if (mech == ImageFileFormat::Bmp ||
mech == ImageFileFormat::Tiff ||
mech == ImageFileFormat::Jfif) {
m_capImageFileFormat = mech;
return success();
}
else
return badValue();
}
return CapSupGetAllReset < ImageFileFormat, ImageFileFormat, CapType::IImageFileFormat>(msg, data, { ImageFileFormat::Bmp, ImageFileFormat::Tiff,ImageFileFormat::Jfif },
m_capImageFileFormat, ImageFileFormat::Bmp, m_capImageFileFormat == ImageFileFormat::Bmp ? 0 : (m_capImageFileFormat == ImageFileFormat::Tiff ? 1 : 2), 0);
};
//custom define
m_query[CapType::IAutomaticDeskew] = msgSupportGetAllSetReset;
m_caps[CapType::IAutomaticDeskew] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapType::IAutomaticDeskew), msg == Msg::Set ? to_string((int)data.currentItem<CapType::IAutomaticDeskew>()) : "");
if (Msg::Set == msg) {
auto atuodsw = data.currentItem<CapType::IAutomaticDeskew>();
m_scanparam->autodescrew = (bool)atuodsw;
return success();
}
return CapSupGetAllReset<BYTE, bool, CapType::IAutomaticDeskew>(msg, data, m_scanparam->autodescrew, true);
};
m_query[(CapType)(CapTypeEx::TwEx_SwitchFrontBack)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_SwitchFrontBack)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_SwitchFrontBack), msg == Msg::Set ? to_string((int)data.currentItem<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
if ((!m_scanparam->is_duplex) && mech == TRUE)
return badValue();
m_scanparam->is_switchfrontback = mech;
return success();
}
return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_SwitchFrontBack>(msg, data, m_scanparam->is_switchfrontback, false);
//return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_SwitchFrontBack>(msg, data, { FALSE,TRUE }, m_scanparam->is_switchfrontback, (Bool)false, m_scanparam->is_switchfrontback ? 1 : 0, 0);
};
m_query[CapType::IAutomaticRotate] = msgSupportGetAllSetReset;
m_caps[CapType::IAutomaticRotate] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapType::IAutomaticRotate), msg == Msg::Set ? to_string((int)data.currentItem<CapType::IAutomaticRotate>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::IAutomaticRotate>();
m_scanparam->is_autotext = (bool)mech;
if (mech)
m_scanparam->imageRotateDegree = 0.0f;
return success();
}
return CapSupGetAllReset<BYTE, bool, CapType::IAutomaticRotate>(msg, data, m_scanparam->is_autotext, false);
};
m_query[CapType::IAutomaticCropUsesFrame] = msgSupportGetAll;
m_caps[CapType::IAutomaticCropUsesFrame] = [this](Msg msg, Capability& data)->Result {
return CapSupGetAll<BYTE, bool, CapType::IAutomaticCropUsesFrame>(msg, data, m_scanparam->is_autocrop, false);
};
m_query[CapType::AutoScan] = msgSupportGetAllSetReset;
m_caps[CapType::AutoScan] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapType::AutoScan), msg == Msg::Set ? to_string((int)data.currentItem<CapType::AutoScan>()) : "");
if (Msg::Set == msg) {
auto autoscan = data.currentItem<CapType::AutoScan>();
m_autoscan = autoscan;
return success();
}
//return CapSupGetAllReset<Bool, Bool, CapType::AutoScan>(msg, data, { FALSE,TRUE }, m_autoscan, Bool(true), m_autoscan ? 1 : 0, 0);
return CapSupGetAllReset<Bool, Bool, CapType::AutoScan>(msg, data, m_autoscan, TRUE);
};
m_query[CapType(CapTypeEx::TwEx_IHighImageQuality)] = msgSupportGetAllSetReset;
m_caps[CapType(CapTypeEx::TwEx_IHighImageQuality)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IHighImageQuality), msg == Msg::Set ? to_string((int)data.currentItem<BOOL>()) : "");
if (Msg::Set == msg) {
auto tmp = data.currentItem<BOOL>();
m_scanparam->is_high_imagequality = tmp;
return success();
}
//return CapSupGetAllReset<Bool, Bool, CapType::AutoScan>(msg, data, { FALSE,TRUE }, m_autoscan, Bool(true), m_autoscan ? 1 : 0, 0);
return CapSupGetAllResetEx<bool, Bool, (CapType)CapTypeEx::TwEx_IHighImageQuality>(msg, data, m_scanparam->is_high_imagequality, false);
};
m_query[CapType::IAutoSize] = msgSupportGetAllSetReset;
m_caps[CapType::IAutoSize] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapType::IAutoSize), msg == Msg::Set ? to_string((int)data.currentItem<CapType::IAutoSize>()) : "");
if (Msg::Set == msg) {
auto autosize = data.currentItem<CapType::IAutoSize>();
if (autosize == AutoSize::Auto) {
if (m_scanparam->papertype == (BYTE)PaperSize::UsStatement) {
m_scanparam->is_autocrop = 0;
m_autoboarderdetcet = false;
}
else {
m_scanparam->is_autocrop = 1;
m_scanparam->papertype = (BYTE)Twpp::PaperSize::None;
m_scanparam->paperAlign = PaperAlign::Rot0;
m_autoboarderdetcet = true;
}
}
else {
m_autoboarderdetcet = false;
m_scanparam->is_autocrop = 0;
}
m_autosize = (UInt16)autosize;
return success();
}
return CapSupGetAllReset<UInt16, AutoSize, CapType::IAutoSize>(msg, data, { AutoSize::None, AutoSize::Auto }, m_autosize, AutoSize::None, (m_autosize == (UInt16)AutoSize::Auto) ? 1 : 0, 0);
};
m_query[CapType::IAutomaticBorderDetection] = msgSupportGetAllSetReset;
m_caps[CapType::IAutomaticBorderDetection] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapType::IAutomaticBorderDetection), msg == Msg::Set ? to_string((int)data.currentItem<CapType::IAutomaticBorderDetection>()) : "");
if (Msg::Set == msg) {
auto autodetectborder = data.currentItem<CapType::IAutomaticBorderDetection>();
if (autodetectborder) {
if (m_scanparam->papertype != (BYTE)PaperSize::UsStatement) {
m_scanparam->is_autocrop = true;
m_scanparam->papertype = (BYTE)Twpp::PaperSize::None;
m_scanparam->paperAlign = PaperAlign::Rot0;
m_autosize = (UInt16)AutoSize::Auto;
}
}
else {
m_autosize = (UInt16)AutoSize::None;
}
m_autoboarderdetcet = autodetectborder;
return success();
}
return CapSupGetAllReset<Bool, Bool, CapType::IAutomaticBorderDetection>(msg, data, { false,true }, m_autoboarderdetcet, false, m_autoboarderdetcet ? 1 : 0, 0);
};
//m_query[CapType::IImageMerge] = msgSupportGetAllSetReset;
//m_caps[CapType::IImageMerge] = [this](Msg msg, Capability& data)->Result {
// if (Msg::Set == msg) {
// auto autocrop = data.currentItem<CapType::IImageMerge>();
// m_scanparam->en_fold = (BYTE)autocrop;
// if ((UInt16)autocrop != 0){
// m_scanparam->is_duplex = 1;
// m_scanparam->autodescrew = 1;//<2F>ϲ<EFBFBD><CFB2><EFBFBD><EFBFBD><EFBFBD>ʱ Ĭ<><C4AC><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>ƫ
// m_scanparam->is_autodiscradblank_normal = m_scanparam->is_autodiscradblank_vince = 0;
// }
// return success();
// }
// return CapSupGetAllResetEx<BYTE, UInt16, CapType::IImageMerge>(msg, data, m_scanparam->en_fold, 0);
//};
m_query[CapType(CapTypeEx::TwEx_EnFold)] = msgSupportGetAllSetReset;
m_caps[CapType(CapTypeEx::TwEx_EnFold)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_EnFold), msg == Msg::Set ? to_string((int)data.currentItem<Int32>()) : "");
if (Msg::Set == msg) {
auto autocrop = data.currentItem<Int32>();
m_scanparam->en_fold = (Int32)autocrop;
if ((UInt16)autocrop != 0) {
m_scanparam->is_duplex = 1;
m_scanparam->autodescrew = 1;//<2F>ϲ<EFBFBD><CFB2><EFBFBD><EFBFBD><EFBFBD>ʱ Ĭ<><C4AC><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>ƫ
m_scanparam->is_autodiscradblank_normal = m_scanparam->is_autodiscradblank_vince = 0;
}
return success();
}
return CapSupGetAllResetEx<BYTE, Int32, (CapType)CapTypeEx::TwEx_EnFold>(msg, data, m_scanparam->en_fold, 0);
//return CapSupGetAllResetEx<BYTE, Int32, (CapType)CapTypeEx::TwEx_EnFold>(msg, data, { 0,1 }, m_scanparam->en_fold, 0, m_scanparam->en_fold ? 1 : 0, 0);
};
m_query[CapType::IAutoDiscardBlankPages] = msgSupportGetAllSetReset;
m_caps[CapType::IAutoDiscardBlankPages] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapType::IAutoDiscardBlankPages), msg == Msg::Set ? to_string((int)data.currentItem<CapType::IAutoDiscardBlankPages>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::IAutoDiscardBlankPages>();
if ((mech == DiscardBlankPages::Auto) || (mech == DiscardBlankPages::Disabled)||((int)mech == 65535))
{
if ((int)mech == 65535 || mech == DiscardBlankPages::Auto)
{
m_scanparam->is_autodiscradblank_normal = 1;
m_scanparam->is_duplex = 1;
m_scanparam->en_fold = 0;
m_scanparam->is_autodiscradblank_vince = 0;
}
else
{
m_scanparam->is_autodiscradblank_normal = 0;
}
return success();
}
return badValue();
}
DiscardBlankPages autodiscradblank;
if (Msg::GetDefault == msg || (Msg::Reset == msg)) {
m_scanparam->is_autodiscradblank_normal = false;
}
m_scanparam->is_autodiscradblank_normal ? (autodiscradblank = DiscardBlankPages::Auto) : (autodiscradblank = DiscardBlankPages::Disabled);
return CapSupGetAllReset<DiscardBlankPages, DiscardBlankPages, CapType::IAutoDiscardBlankPages>(msg, data, autodiscradblank, DiscardBlankPages::Disabled);
};
/*costom caps*/
//<2F><><EFBFBD><EFBFBD><EFBFBD>հ<EFBFBD>ҳ<EFBFBD><D2B3>Ʊ
m_query[(CapType)(CapTypeEx::TwEx_IAutoDiscardBlankVince)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_IAutoDiscardBlankVince)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IAutoDiscardBlankVince), msg == Msg::Set ? to_string((int)data.currentItem<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
m_scanparam->is_autodiscradblank_vince = mech;
if (mech) {
m_scanparam->is_duplex = 1;
m_scanparam->en_fold = 0;
m_scanparam->is_autodiscradblank_normal = 0;
}
return success();
}
return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_IAutoDiscardBlankVince>(msg, data, m_scanparam->is_autodiscradblank_vince, false);
//return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_IAutoDiscardBlankVince>(msg, data, { FALSE,TRUE }, m_scanparam->is_autodiscradblank_vince, Bool(false), m_scanparam->is_autodiscradblank_vince ? 1 : 0, 0);
};
m_query[(CapType)(CapTypeEx::TwEx_IBackRotate180)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_IBackRotate180)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IBackRotate180), msg == Msg::Set ? to_string((int)data.currentItem<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
if (mech)
{
if (!m_scanparam->is_duplex)
{
return badValue();
}
}
m_scanparam->is_backrotate180 = mech;
return success();
}
return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_IBackRotate180>(msg, data, m_scanparam->is_backrotate180, false);
//return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_IBackRotate180>(msg, data, { FALSE,TRUE }, m_scanparam->is_backrotate180, Bool(false), m_scanparam->is_backrotate180 ? 1 : 0, 0);
};
//<2F><><EFBFBD>ڿ<EFBFBD>
m_query[(CapType)(CapTypeEx::TwEx_IFillBackground)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_IFillBackground)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IFillBackground), msg == Msg::Set ? to_string((int)data.currentItem<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
m_scanparam->fillbackground = mech;
return success();
}
return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_IFillBackground>(msg, data, m_scanparam->fillbackground, true);
//return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_IFillBackground>(msg, data, { FALSE,TRUE }, m_scanparam->fillbackground, Bool(true), m_scanparam->fillbackground ? 1 : 0, 1);
};
//<2F>ü<EFBFBD><C3BC><EFBFBD>ƫ<EFBFBD><C6AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
m_query[(CapType)(CapTypeEx::TwEx_CroporDesaskewIndent)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_CroporDesaskewIndent)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_CroporDesaskewIndent), msg == Msg::Set ? to_string((int)data.currentItem<UInt32>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<UInt32>();
if ((mech > 30 || mech < 5) && ((bool)m_scanparam->is_autocrop == true))
return badValue();
m_scanparam->indent = mech;
return success();
}
return CapSupGetAllResetEx<int, UInt32, (CapType)CapTypeEx::TwEx_CroporDesaskewIndent>(msg, data, m_scanparam->indent, 5);
};
//<2F>Զ<EFBFBD><D4B6>ü<EFBFBD><C3BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
m_query[(CapType)(CapTypeEx::TwEx_CropNoise)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_CropNoise)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_CropNoise), msg == Msg::Set ? to_string((int)data.currentItem<UInt32>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<UInt32>();
if ((mech > 20 || mech < 1) && ((bool)m_scanparam->is_autocrop == true))
return badValue();
m_scanparam->noise = mech;
return success();
}
return CapSupGetAllResetEx<int, UInt32, (CapType)CapTypeEx::TwEx_CropNoise>(msg, data, m_scanparam->noise, 8);
};
//<2F>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD>к;<D0BA>ƫ<EFBFBD>Ķ<EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>ֵ
m_query[(CapType)(CapTypeEx::TwEx_CroporDesaskewThreshold)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_CroporDesaskewThreshold)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_CroporDesaskewThreshold), msg == Msg::Set ? to_string((int)data.currentItem<UInt32>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<UInt32>();
if (mech > 50 || mech < 30)
return badValue();
m_scanparam->AutoCrop_threshold = mech;
return success();
}
return CapSupGetAllResetEx<int, UInt32, (CapType)CapTypeEx::TwEx_CroporDesaskewThreshold>(msg, data, m_scanparam->AutoCrop_threshold, 40);
};
//<2F>ڿ<EFBFBD><DABF><EFBFBD><EFBFBD>ʽ
m_query[(CapType)(CapTypeEx::TwEx_FillBackgroundMode)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_FillBackgroundMode)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_FillBackgroundMode), msg == Msg::Set ? to_string((int)data.currentItem<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
m_scanparam->is_convex = mech;
return success();
}
return CapSupGetAllResetEx<bool, Bool, (CapType)CapTypeEx::TwEx_FillBackgroundMode>(msg, data, m_scanparam->is_convex, Bool(true));
};
//<2F><EFBFBD><EEB4A9>
m_query[(CapType)(CapTypeEx::TwEx_IFillHole)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_IFillHole)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IFillHole), msg == Msg::Set ? to_string((int)data.currentItem<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
m_scanparam->fillhole.is_fillhole = mech;
return success();
}
return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_IFillHole>(msg, data, m_scanparam->fillhole.is_fillhole, false);
//return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_IFillHole>(msg, data, { FALSE,TRUE }, m_scanparam->fillhole.is_fillhole, Bool(false), m_scanparam->fillhole.is_fillhole ? 1 : 0, 0);
};
m_query[(CapType)(CapTypeEx::TwEx_IFillHoleRatio)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_IFillHoleRatio)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IFillHoleRatio), msg == Msg::Set ? to_string((int)data.currentItem<Int32>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Int32>();
if (mech > 0 && mech < 50) {
m_scanparam->fillhole.fillholeratio = (int)mech;
m_scanparam->fillholeratio_up = m_scanparam->fillholeratio_down = m_scanparam->fillholeratio_left = m_scanparam->fillholeratio_right = int(mech);
return success();
}
return badValue();
}
return CapSupGetAllResetEx<int, Int32, (CapType)CapTypeEx::TwEx_IFillHoleRatio>(msg, data, m_scanparam->fillhole.fillholeratio, 10);
};
//<2F><><EFBFBD><EFBFBD><EFBFBD>Ż<EFBFBD>
m_query[(CapType)(CapTypeEx::TwEx_IDetachNoise)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_IDetachNoise)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IDetachNoise), msg == Msg::Set ? to_string((int)data.currentItem<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
if (mech) {
if (m_scanparam->pixtype != 0)
return badValue();
}
m_scanparam->detachnoise.is_detachnoise = mech;
return success();
}
return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_IDetachNoise>(msg, data, m_scanparam->detachnoise.is_detachnoise, false);
//return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_IDetachNoise>(msg, data, { FALSE,TRUE }, m_scanparam->detachnoise.is_detachnoise, FALSE, m_scanparam->detachnoise.is_detachnoise ? 1 : 0, 0);
};
m_query[(CapType)(CapTypeEx::TwEx_IDetachNoiseValue)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_IDetachNoiseValue)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IDetachNoiseValue), msg == Msg::Set ? to_string((int)data.currentItem<Int32>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Int32>();
if (mech > 9 && mech < 51) {
m_scanparam->detachnoise.detachnoise = (int)mech;
return success();
}
return badValue();
}
return CapSupGetAllResetEx<int, Int32, (CapType)CapTypeEx::TwEx_IDetachNoiseValue>(msg, data, m_scanparam->detachnoise.detachnoise, 10);
};
//<2F><><EFBFBD><EFBFBD><EFBFBD>Ƴ<EFBFBD>
m_query[(CapType)(CapTypeEx::TwEx_IFadeBack)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_IFadeBack)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IFadeBack), msg == Msg::Set ? to_string((int)data.currentItem<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
if (mech)
{
if (m_scanparam->pixtype != 2)
return badValue();
}
m_scanparam->fadeback = mech;
return success();
}
return CapSupGetAllResetEx<bool, Bool, (CapType)CapTypeEx::TwEx_IFadeBack>(msg, data, m_scanparam->fadeback, false);
};
m_query[(CapType)(CapTypeEx::TwEx_IFadeBackValue)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_IFadeBackValue)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IFadeBackValue), msg == Msg::Set ? to_string((int)data.currentItem<Int32>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Int32>();
if (mech > 0 && mech < 129) {
m_scanparam->fadeback_range = (int)mech;
return success();
}
return badValue();
}
return CapSupGetAllResetEx<int, Int32, (CapType)CapTypeEx::TwEx_IFadeBackValue>(msg, data, m_scanparam->fadeback_range, 40);
};
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
m_query[(CapType)(CapTypeEx::TwEx_IMultiOutputRed)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_IMultiOutputRed)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IMultiOutputRed), msg == Msg::Set ? to_string((int)data.currentItem<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
if (m_scanparam->pixtype == (BYTE)PixelType::Rgb &&(!m_scanparam->en_multi_output))
m_scanparam->multi_output_red = mech;
else
return badValue();
//m_scanparam->multi_output_red = 0;//<2F>Dz<EFBFBD>ɫ <20><><EFBFBD><EFBFBD>ʹ<EFBFBD>ö<EFBFBD><C3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return success();
}
return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_IMultiOutputRed>(msg, data, m_scanparam->multi_output_red, false);
//return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_IMultiOutputRed>(msg, data, { FALSE,TRUE }, m_scanparam->multi_output_red, FALSE, m_scanparam->multi_output_red ? 1 : 0, 0);
};
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>
m_query[(CapType)(CapTypeEx::TwEx_IEnMultiOutPut)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_IEnMultiOutPut)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IEnMultiOutPut), msg == Msg::Set ? to_string((int)data.currentItem<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
if (m_scanparam->pixtype == (BYTE)PixelType::Rgb && (!m_scanparam->multi_output_red))
m_scanparam->en_multi_output = mech;
else
return badValue();
return success();
}
return CapSupGetAllResetEx<bool, Bool, (CapType)CapTypeEx::TwEx_IEnMultiOutPut>(msg, data, m_scanparam->en_multi_output, false);
//return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_IEnMultiOutPut>(msg, data, { FALSE,TRUE }, m_scanparam->en_multi_output, FALSE, m_scanparam->en_multi_output ? 1 : 0, 0);
};
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
m_query[(CapType)(CapTypeEx::TwEx_IEnMultiOutPutType)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_IEnMultiOutPutType)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IEnMultiOutPutType), msg == Msg::Set ? to_string((int)data.currentItem<Int32>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Int32>();
if (m_scanparam->pixtype == (BYTE)PixelType::Rgb && (!m_scanparam->multi_output_red) && m_scanparam->en_multi_output)
m_scanparam->multioutput = mech;
else
return badValue();
return success();
}
return CapSupGetAllResetEx<int8_t, Int32, (CapType)CapTypeEx::TwEx_IEnMultiOutPutType>(msg, data, m_scanparam->multioutput, 0);
};
//<2F><><EFBFBD><EFBFBD><E2BFA8><EFBFBD><EFBFBD>
m_query[(CapType)(CapTypeEx::TwEx_HsvCorrect)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_HsvCorrect)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_HsvCorrect), msg == Msg::Set ? to_string((int)data.currentItem<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
if (mech){
if (m_scanparam->pixtype != (int)PixelType::Rgb)
return badValue();
}
m_scanparam->hsvcorrect = mech;
return success();
}
return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_HsvCorrect>(msg, data, m_scanparam->hsvcorrect, false);
//return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_HsvCorrect>(msg, data, { FALSE,TRUE }, m_scanparam->hsvcorrect, FALSE, m_scanparam->hsvcorrect ? 1 : 0, 0);
};
m_query[CapType::IFilter] = msgSupportGetAllSetReset;
m_caps[CapType::IFilter] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapType::IFilter), msg == Msg::Set ? to_string((int)data.currentItem<CapType::IFilter>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::IFilter>();
if (mech == Filter::None || mech == Filter::Red || mech == Filter::Green || mech == Filter::Blue) {
if (((Filter)mech != Filter::None) && (m_scanparam->pixtype == (int)PixelType::Rgb))
return badValue();
m_scanparam->filter = (BYTE)mech;
if (mech != Filter::None) {
m_scanparam->enhance_color = (BYTE)Enchace_Color::Enhance_None;
}
return success();
}
return badValue();
}
return CapSupGetAllReset<BYTE, Filter, CapType::IFilter>(msg, data, { Filter::Red,Filter::Green,Filter::Blue,Filter::None }, m_scanparam->filter, Filter::None, m_scanparam->filter, 3);
};
//<2F><>ɫ<EFBFBD><C9AB>ǿ
m_query[(CapType)(CapTypeEx::TwEx_IEnhanceColor)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_IEnhanceColor)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IEnhanceColor), msg == Msg::Set ? to_string((int)data.currentItem<Int16>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Int16>();
if (m_scanparam->pixtype == (int)PixelType::Rgb)
{
m_scanparam->enhance_color = (BYTE)Enchace_Color::Enhance_None;
m_scanparam->filter = (BYTE)Filter::None;
return badValue();
}
else
{
if (mech == Enchace_Color::Enhance_None || mech == Enchace_Color::Enhance_Red || mech == Enchace_Color::Enhance_Green || mech == Enchace_Color::Enhance_Blue)
{
m_scanparam->enhance_color = (BYTE)mech;
if (mech != (BYTE)Enchace_Color::Enhance_None)
m_scanparam->filter = (BYTE)Filter::None;
return success();
}
}
}
return CapSupGetAllResetEx<BYTE, Enchace_Color, (CapType)CapTypeEx::TwEx_IEnhanceColor>(msg, data, m_scanparam->enhance_color, (Enchace_Color)0);
//return CapSupGetAllResetEx<BYTE, Enchace_Color, (CapType)CapTypeEx::TwEx_IEnhanceColor>(msg, data, { Enchace_Color::Enhance_None,Enchace_Color::Enhance_Red,Enchace_Color::Enhance_Green,Enchace_Color::Enhance_Blue }, m_scanparam->enhance_color, Enchace_Color::Enhance_None, m_scanparam->enhance_color, 0);
};
m_query[(CapType)(CapTypeEx::TwEx_Sharpen)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_Sharpen)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_Sharpen), msg == Msg::Set ? to_string((int)data.currentItem<Int16>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Int16>();
if (m_scanparam->pixtype == (int)PixelType::BlackWhite)
return badValue();
m_scanparam->sharpen = (BYTE)mech;
return success();
}
return CapSupGetAllResetEx<BYTE, SharpenBlur, (CapType)CapTypeEx::TwEx_Sharpen>(msg, data, m_scanparam->sharpen, SharpenBlur::Sharpen_None);
//return CapSupGetAllResetEx<BYTE, SharpenBlur, (CapType)CapTypeEx::TwEx_Sharpen>(msg, data, { SharpenBlur::Sharpen_None,SharpenBlur::Sharpen_Normal,SharpenBlur::Sharpen_More,SharpenBlur::Sharpen_Blur,SharpenBlur::Sharpen_Blur_More }, m_scanparam->sharpen, SharpenBlur::Sharpen_None, m_scanparam->sharpen, 0);
};
/*<2A><><EFBFBD><EFBFBD> <20>Աȶ<D4B1> gamma range<67><65><EFBFBD><EFBFBD> Range <20><><EFBFBD><EFBFBD>*/
m_query[CapType::IBrightness] = msgSupportGetAllSetReset;
m_caps[CapType::IBrightness] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapType::IBrightness), msg == Msg::Set ? to_string((float)data.currentItem<CapType::IBrightness>()) : "");
switch (msg) {
case Msg::Get:
data = Capability::createRange<CapType::IBrightness>(Fix32(-1000.0f), Fix32(1000.0f), Fix32(333.3f), Fix32(m_scanparam->brightness), Fix32(0.0));
return success();
case Msg::GetCurrent:
data = Capability::createOneValue<CapType::IBrightness>(Fix32(m_scanparam->brightness));
return success();
case Msg::GetDefault:
case Msg::Reset:
m_scanparam->brightness = 0.0f;
data = Capability::createOneValue<CapType::IBrightness>(Fix32(0.0f));
return success();
case Msg::Set: {
auto mech = data.currentItem<CapType::IBrightness>();
if (mech > 1000.0f || mech < -1000.0f)
return badValue();
m_scanparam->brightness = (float)mech;
return success();
}
default:
return capBadOperation();
}
};
m_query[CapType::IContrast] = msgSupportGetAllSetReset;
m_caps[CapType::IContrast] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapType::IContrast), msg == Msg::Set ? to_string((float)data.currentItem<CapType::IContrast>()) : "");
switch (msg) {
case Msg::Get:
data = Capability::createRange<CapType::IContrast>(Fix32(-1000.0f), Fix32(1000.0f), Fix32(333.3f), Fix32(m_scanparam->contrast), Fix32(0.0));
return success();
case Msg::GetCurrent:
data = Capability::createOneValue<CapType::IContrast>(Fix32(m_scanparam->contrast));
return success();
case Msg::GetDefault:
case Msg::Reset:
m_scanparam->contrast = 0.0f;
data = Capability::createOneValue<CapType::IContrast>(Fix32(0.0f));
return success();
case Msg::Set: {
auto mech = data.currentItem<CapType::IContrast>();
if (mech > 1000.0f || mech < -1000.0f)
return badValue();
m_scanparam->contrast = (float)mech;
return success();
}
default:
return capBadOperation();
}
};
m_query[CapType::IGamma] = msgSupportGetAllSetReset;
m_caps[CapType::IGamma] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapType::IGamma), msg == Msg::Set ? to_string((float)data.currentItem<CapType::IGamma>()) : "");
switch (msg) {
case Msg::Get:
data = Capability::createRange<CapType::IGamma>(Fix32(0.0f), Fix32(5.0f), Fix32(1.0f), Fix32(m_scanparam->gamma), Fix32(1.0));
return success();
case Msg::GetCurrent:
data = Capability::createOneValue<CapType::IGamma>(Fix32(m_scanparam->gamma));
return success();
case Msg::GetDefault:
case Msg::Reset:
m_scanparam->gamma = 1.0f;
data = Capability::createOneValue<CapType::IGamma>(Fix32(0.0f));
return success();
case Msg::Set: {
auto mech = data.currentItem<CapType::IGamma>();
if (mech > 5.0f || mech < 0.0f)
return badValue();
m_scanparam->gamma = (float)mech;
return success();
}
default:
return capBadOperation();
}
};
/*<2A><><EFBFBD><EFBFBD>ΪӲ<CEAA><D3B2>Э<EFBFBD><D0AD>*/
m_query[(CapType)(CapTypeEx::TwEx_ScrewDetectEnable)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_ScrewDetectEnable)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_ScrewDetectEnable), msg == Msg::Set ? to_string((float)data.currentItem<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
m_scanparam->hardwarecaps.en_skrewdetect = mech;
return success();
}
Bool en = m_scanparam->hardwarecaps.en_skrewdetect == 0 ? Bool(false) : Bool(true);
return CapSupGetAllResetEx<Bool, Bool, (CapType)(CapTypeEx::TwEx_ScrewDetectEnable)>(msg, data,(Bool)m_scanparam->hardwarecaps.en_skrewdetect , Bool(true));
//return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_ScrewDetectEnable>(msg, data, { FALSE ,TRUE }, m_scanparam->hardwarecaps.en_skrewdetect, TRUE, m_scanparam->hardwarecaps.en_skrewdetect ? 1 : 0, 1);
};
m_query[(CapType)(CapTypeEx::TwEx_ScrewLevel)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_ScrewLevel)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_ScrewLevel), msg == Msg::Set ? to_string((float)data.currentItem<UInt32>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<UInt32>();
if (mech >= 1 && mech <= 5) {
m_scanparam->hardwarecaps.skrewdetectlevel = mech;
return success();
}
return badValue();
}
return CapSupGetAllResetEx<BYTE, UInt32, (CapType)CapTypeEx::TwEx_ScrewLevel>(msg, data, m_scanparam->hardwarecaps.skrewdetectlevel, (UInt32)3);
//return oneValGetSet<UInt8>(msg,data,m_scanparam->hardwarecaps.skrewdetectlevel,3);
};
//װ<><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
m_query[(CapType)(CapTypeEx::TwEx_StableDetectEnable)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_StableDetectEnable)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_StableDetectEnable), msg == Msg::Set ? to_string((float)data.currentItem<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
m_scanparam->hardwarecaps.en_stapledetect = mech;
return success();
}
return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_StableDetectEnable>(msg, data, m_scanparam->hardwarecaps.en_stapledetect, false);
//return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_StableDetectEnable>(msg, data, { FALSE,TRUE }, m_scanparam->hardwarecaps.en_stapledetect, FALSE, m_scanparam->hardwarecaps.en_stapledetect==0 ? 0 : 1, 0);
};
//<2F>۽Ǽ<DBBD><C7BC><EFBFBD>
m_query[(CapType)(CapTypeEx::TwEx_DogEarDelection)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_DogEarDelection)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_DogEarDelection), msg == Msg::Set ? to_string((float)data.currentItem<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
m_scanparam->is_dogeardetection = mech;
return success();
}
return CapSupGetAllResetEx<BYTE, Bool, (CapType)CapTypeEx::TwEx_DogEarDelection>(msg, data, m_scanparam->is_dogeardetection, FALSE);
};
//<2F>۽Ǽ<DBBD><C7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>۶<EFBFBD><DBB6>㵽ʵ<E3B5BD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD>
m_query[(CapType)(CapTypeEx::TwEx_DogEarDistance)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_DogEarDistance)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_DogEarDistance), msg == Msg::Set ? to_string((float)data.currentItem<UInt32>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<UInt32>();
if (mech >= 10 && mech <= 300)
m_scanparam->dogeardistance = mech;
else
return badValue();
return success();
}
return CapSupGetAllResetEx<UInt32, UInt32, (CapType)CapTypeEx::TwEx_DogEarDistance>(msg, data, m_scanparam->dogeardistance, 70);
};
//˫<>ż<EFBFBD><C5BC><EFBFBD> <20><><EFBFBD>ٷ<EFBFBD><D9B7><EFBFBD>׼<EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>Э<EFBFBD><D0AD><EFBFBD>޸<EFBFBD>Ϊbool<6F><6C> <20><><EFBFBD><EFBFBD>Уʹ<D0A3><CAB9>bool<6F><6C><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ñ<EFBFBD>׼twainЭ<6E><D0AD>
m_query[CapType::DoubleFeedDetection] = msgSupportGetAllSetReset;
m_caps[CapType::DoubleFeedDetection] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapType::DoubleFeedDetection), msg == Msg::Set ? to_string((float)data.currentItem<UInt16>()) : "");
std::vector<std::string> names;
Twain_config().GetOrSetDoubleNames(names,true);
FileTools::writelog(log_INFO, " DoubleFeedDetection "+ FileTools::GetProcessName());
if (std::find(names.begin(), names.end(), FileTools::to_web_utf(FileTools::String2Wstring(FileTools::GetProcessName()))) == names.end()) {
FileTools::writelog(log_INFO, " DoubleFeedDetection 11111 ");
switch (msg) {
case Msg::Get:
data = Capability::createEnumeration<UInt16>(CapType::DoubleFeedDetection, { 0 ,1 }, m_scanparam->hardwarecaps.en_doublefeed ? 0 : 1, 0);
return { ReturnCode::Success, ConditionCode::Success };
case Msg::GetCurrent:
data = Capability::createOneValue<UInt16>(CapType::DoubleFeedDetection, (UInt16)m_scanparam->hardwarecaps.en_doublefeed ? 0 : 1);
return { ReturnCode::Success, ConditionCode::Success };
case Msg::Reset:
case Msg::GetDefault:
m_scanparam->hardwarecaps.en_doublefeed = 1;
data = Capability::createOneValue<UInt16>(CapType::DoubleFeedDetection, 0);
return { ReturnCode::Success, ConditionCode::Success };
case Msg::Set: {
auto mech = data.currentItem<UInt16>();
m_scanparam->hardwarecaps.en_doublefeed = mech ? 0 : 1;
return success();
}
default:
return { ReturnCode::Failure, ConditionCode::CapBadOperation };
}
}
else{
FileTools::writelog(log_INFO, " DoubleFeedDetection 22222 ");
if (Msg::Set == msg) {
auto mech = data.currentItem<UInt16>();
m_scanparam->hardwarecaps.en_doublefeed = mech ? 1 : 0;
return success();
}
return CapSupGetAllResetEx<BYTE, UInt16, CapType::DoubleFeedDetection>(msg, data, m_scanparam->hardwarecaps.en_doublefeed, TRUE);
}
};
#ifdef G200
//<2F>͹<EFBFBD><CDB9><EFBFBD>ģʽ
m_query[(CapType)(CapTypeEx::TwEx_LowPowerMode)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_LowPowerMode)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_LowPowerMode), msg == Msg::Set ? to_string((float)data.currentItem<UInt32>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<UInt32>();
m_scanparam->hardwarecaps.lowpowermode = (LowPowerMode)mech;
return success();
}
return CapSupGetAllResetEx<LowPowerMode, UInt32, (CapType)CapTypeEx::TwEx_LowPowerMode>(msg, data, m_scanparam->hardwarecaps.lowpowermode, LowPowerMode::Min_30);
//return CapSupGetAllResetEx<LowPowerMode, UInt32, (CapType)CapTypeEx::TwEx_LowPowerMode>(msg, data,
// { LowPowerMode::Min_None,LowPowerMode::Min_5,LowPowerMode::Min_10,LowPowerMode::Min_20, LowPowerMode::Min_30, LowPowerMode::Min_60, LowPowerMode::Min_120, LowPowerMode::Min_240 },
// m_scanparam->hardwarecaps.lowpowermode, LowPowerMode::Min_30, (BYTE)m_scanparam->hardwarecaps.lowpowermode, 4);
};
#endif // LANXUM
#if defined G200 || defined G300
#ifndef ANDROIDSERIAL
//<2F><>ֽɨ<D6BD><C9A8>
m_query[(CapType)(CapTypeEx::TwEx_IToBeScan)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_IToBeScan)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IToBeScan), msg == Msg::Set ? to_string((float)data.currentItem<BOOL>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<BOOL>();
m_scanparam->hardwarecaps.is_autopaper = mech;
m_scanparam->autopaper_timeout = 15;
if (mech)
m_scanparam->scannum = -1;
return success();
}
return CapSupGetAllResetEx<uint8_t, BOOL, (CapType)CapTypeEx::TwEx_IToBeScan>(msg, data, m_scanparam->hardwarecaps.is_autopaper, FALSE);
};
m_query[(CapType)(CapTypeEx::TwEx_IToBeScanTimeOut)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_IToBeScanTimeOut)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IToBeScanTimeOut), msg == Msg::Set ? to_string((float)data.currentItem<UInt32>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<UInt32>();
if (mech > 60 || mech < 15)
return badValue();
m_scanparam->autopaper_timeout = mech;
return success();
}
return CapSupGetAllResetEx<int, int, (CapType)CapTypeEx::TwEx_IToBeScanTimeOut>(msg, data, m_scanparam->autopaper_timeout, 15);
};
#endif
#endif
m_query[(CapType)(CapTypeEx::TwEx_CropModel)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_CropModel)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_CropModel), msg == Msg::Set ? to_string((float)data.currentItem<UInt32>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<UInt32>();
if (m_scanparam->fillbackground ||
m_scanparam->autodescrew ||
m_scanparam->is_autocrop ||
m_scanparam->en_fold)
{
return badValue();
}
m_scanparam->normalCrop = (bool)mech;
return success();
}
return CapSupGetAllResetEx<bool, UInt32, (CapType)CapTypeEx::TwEx_CropModel>(msg, data, m_scanparam->normalCrop, false);
};
//ͼ<><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
m_query[(CapType)(CapTypeEx::TwEx_ImageSplit)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_ImageSplit)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_ImageSplit), msg == Msg::Set ? to_string((float)data.currentItem<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
m_scanparam->is_split = mech;
return success();
}
return CapSupGetAllResetEx<bool, Bool, (CapType)CapTypeEx::TwEx_ImageSplit>(msg, data, m_scanparam->is_split, false);
};
//ɫƫУ<C6AB><D0A3>
m_query[(CapType)(CapTypeEx::TwEx_ColorCast)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_ColorCast)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_ColorCast), msg == Msg::Set ? to_string((float)data.currentItem<Bool>()) : "");
if (Msg::Set == msg) {
if (m_scanparam->pixtype != 2)
return badValue();
auto mech = data.currentItem<Bool>();
m_scanparam->is_colorcast = mech;
return success();
}
return CapSupGetAllResetEx<bool, Bool, (CapType)CapTypeEx::TwEx_ColorCast>(msg, data, m_scanparam->is_colorcast, false);
};
m_query[(CapType)(CapTypeEx::TwEx_IHsvFilter)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_IHsvFilter)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_IHsvFilter), msg == Msg::Set ? to_string((float)data.currentItem<Bool>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<Bool>();
if (m_scanparam->pixtype != 2)//color
return badValue();
m_scanparam->hsvFilter = mech?1:0;
return success();
}
bool hsv_v=(bool)(m_scanparam->hsvFilter);
return CapSupGetAllResetEx<bool, Bool, (CapType)CapTypeEx::TwEx_IHsvFilter>(msg, data, hsv_v, false);
};
#ifdef UV
m_query[(CapType)(CapTypeEx::TwEx_UVModel)] = msgSupportGetAllSetReset;
m_caps[(CapType)(CapTypeEx::TwEx_UVModel)] = [this](Msg msg, Capability& data)->Result {
CapabilityPrintf(msg, enum2str(CapTypeEx::TwEx_UVModel), msg == Msg::Set ? to_string((float)data.currentItem<Bool>()) : "");
switch (msg) {
case Msg::Get:{
data = Capability::createOneValue<Bool>((CapType)(CapTypeEx::TwEx_UVModel), Bool(m_scanparam->hardwarecaps.en_uv));
//data = Capability::createEnumeration<Bool>((CapType)(CapTypeEx::TwEx_UVModel), { Bool(),Bool(true) }, Bool(m_scanparam->hardwarecaps.en_uv), 0);
return success();
}
case Msg::Reset:
m_scanparam->hardwarecaps.en_uv = false;
case Msg::GetCurrent:
data = Capability::createOneValue<Bool>((CapType)(CapTypeEx::TwEx_UVModel), m_scanparam->hardwarecaps.en_uv);
return success();
case Msg::GetDefault:
data = Capability::createOneValue<Bool>((CapType)(CapTypeEx::TwEx_UVModel), Bool(false));
return success();
case Msg::Set: {
auto mech = data.currentItem<Bool>();
m_scanparam->hardwarecaps.en_uv = mech?1:0;
return success();
}
default:
return capBadOperation();
}
};
#endif
return success();
}
Result HuagaoDs::identityCloseDs(const Identity&) {
// no need to explicitly release any resources if using RAII
// TWPP will free the whole source on its own after this method
if (guiIndicator->GetSafeHwnd())
guiIndicator->DestroyWindow();
if (guiTwain.get())
guiTwain.reset();
if (guiBridge.get())
guiBridge.reset();
scanner.reset();
bmpData.reset();
if (hMutex)
{
ReleaseMutex(hMutex);
CloseHandle(hMutex);
}
//saveGscanCapSetting();
return success();
}
Result HuagaoDs::pendingXfersGet(const Identity&, PendingXfers& data) {
data.setCount(m_pendingXfers);
return success();
}
Result HuagaoDs::pendingXfersEnd(const Identity&, PendingXfers& data) {
//!< end xfer if set count 0
if (bmpData->size() > 0)
{
bmpData.reset(new std::vector<unsigned char>);
}
int ret = scanner->aquire_bmpdata(*bmpData.get());
if (ret != 0) {
scanner->Set_ErrorCode(0);
if (guiIndicator->GetSafeHwnd())
guiIndicator->ShowWindow(SW_HIDE);
if (ret != -1) {
int index = scanner->geterrorindex();
if (ret == 82 && ((typeid(*scanner.get()) == typeid(GScanO1003399))))
showmsg("<EFBFBD><EFBFBD>ʾ", "<EFBFBD>ڵ<EFBFBD>" + to_string(index) + "ҳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>۽ǣ<EFBFBD>ֹͣɨ<EFBFBD>", ret);
else if (ret == 75 && ((typeid(*scanner.get()) == typeid(GScanO1003399))))
showmsg("<EFBFBD><EFBFBD>ʾ", "<EFBFBD>ڵ<EFBFBD>" + to_string(index) + "ҳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֹͣɨ<EFBFBD>", ret);
else if (ret == 81 && ((typeid(*scanner.get()) == typeid(GScanO1003399))))
showmsg("<EFBFBD><EFBFBD>ʾ", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", ret);
else
showmsg("<EFBFBD><EFBFBD>ʾ", msgs[(UsbSupported)ret], ret);
FileTools::writelog(log_ERROR, msgs[(UsbSupported)ret]);
#ifndef G200
scanner->clear_hwerror();
#endif // G200
}
else
{
if (!(m_scanparam->is_autodiscradblank_normal || m_scanparam->is_autodiscradblank_vince))
{
int num = scanner->get_scannum() * (m_scanparam->is_duplex ? 2 : 1) * (m_scanparam->multi_output_red ? 2 : 1) / (m_scanparam->en_fold ? 2 : 1) * (m_scanparam->is_split ? 2 : 1)
* (m_scanparam->en_multi_output ? (m_scanparam->multioutput < 0 ? 1 : (m_scanparam->multioutput == 0 ? 3 : 2)) : 1);
if ((num - scanner->get_imgTransfered()) != 0)
{
showmsg("<EFBFBD><EFBFBD>ʾ", msgs[LOSE_IMAGE]);
FileTools::writelog(log_ERROR, msgs[LOSE_IMAGE]);
}
}
}
m_pendingXfers = 0;
if (guiTwain.get()) {
((CTwainUI*)(guiTwain.get()))->EnableID_OKorID_Cancel(true);
//setState(DsState::Enabled);
}
else {
//setState(DsState::Open);
}
}
else {
m_pendingXfers = 1;
//setState( DsState::XferReady );
}
data.setCount(m_pendingXfers);
return success();
}
Result HuagaoDs::pendingXfersReset(const Identity&, PendingXfers& data) {
data.setCount(0);
if (scanner.get())
{
scanner->Stop_scan();
//scanner->reset();
scanner->ResetScanner();
}
//guiIndicator.reset();
if (guiIndicator->GetSafeHwnd())
guiIndicator->DestroyWindow();
if (guiTwain.get()) {
((CTwainUI*)(guiTwain.get()))->EnableID_OKorID_Cancel(true);
}
return success();
}
Result HuagaoDs::setupMemXferGet(const Identity&, SetupMemXfer& data) {
auto bpl = bytesPerLine();
auto max = bpl * static_cast<UInt32>(header()->biHeight);
data.setMinSize(bpl);
data.setPreferredSize(max);
data.setMaxSize(max);
return success();
}
Result HuagaoDs::userInterfaceDisable(const Identity&, UserInterface& ui) {
if (guiTwain.get())
guiTwain.reset();
#if TWPP_DETAIL_OS_WIN
if (guiBridge.get())
guiBridge.reset();
#endif
return success();
}
Result HuagaoDs::userInterfaceEnable(const Identity&, UserInterface& ui) {
m_pendingXfers = 1;
m_memXferYOff = 0;
if (!ui.showUi()) {
// this is an exception when we want to set state explicitly, notifyXferReady can be called only in enabled state
// with hidden UI, the usual workflow DsState::Enabled -> notifyXferReady() -> DsState::XferReady is a single step
if (!scanner->IsConnected())
scanner->open(vid, pid);
if (!scanner->IsConnected())
{
MessageBox(NULL, L"USB<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>USB<53><42><EFBFBD><EFBFBD><EFBFBD>´<EFBFBD><C2B4><EFBFBD>ɨ<EFBFBD><C9A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", L"<EFBFBD><EFBFBD>ʾ", MB_OK | MB_SYSTEMMODAL);
return seqError();
}
#ifndef G200
if (typeid(*scanner.get()) != typeid(GScanO1003399)) {
while (!scanner->Get_Scanner_PaperOn())
{
if (MessageBox(NULL, L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><EFBFBD>", L"<EFBFBD><EFBFBD>ʾ", MB_YESNO | MB_SYSTEMMODAL) == IDNO)
return seqError();
}
}
#endif // !G200
this_thread::sleep_for(chrono::milliseconds(100)); //ɨ<><C9A8>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD>ӳ<EFBFBD> <20><>ֹusb<73><62><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD>Ϣδ<CFA2><CEB4>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ɨ<EFBFBD><C9A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
auto ret = startScan();
//if (ret.status().condition() == Twpp::CC::NoMedia)
// return ret;
if (ret == success()) {
m_pendingXfers = 1;
}
else {
m_pendingXfers = 0;
return seqError();
}
return success();
}
return showTwainUI(ui);
}
Result HuagaoDs::userInterfaceEnableUiOnly(const Identity&, UserInterface& ui) {
// as a minimal source, we do not support GUI that just saves settings
return showTwainUI(ui, true);
}
Result HuagaoDs::imageInfoGet(const Identity&, ImageInfo& data) {
// our image does not change
//if (m_pendingXfers == 0 || bmpData->size() == 0)
if(bmpData->size() == 0)
return success();
auto dib = header();
data.setBitsPerPixel(static_cast<Int16>(dib->biBitCount));
data.setHeight(dib->biHeight);
data.setPixelType(dib->biClrUsed == 2 ? PixelType::BlackWhite : (dib->biClrUsed == 256 ? PixelType::Gray : PixelType::Rgb));
data.setPlanar(false);
data.setWidth(dib->biWidth);
data.setXResolution(m_scanparam->resolution_dst);
data.setYResolution(m_scanparam->resolution_dst);
data.compression(m_compression);
switch (dib->biClrUsed)
{
case 2:
case 256:
data.setSamplesPerPixel(1);
data.bitsPerSample()[0] = 8;
break;
case 0:
data.setSamplesPerPixel(3);
data.bitsPerSample()[0] = 8;
data.bitsPerSample()[1] = 8;
data.bitsPerSample()[2] = 8;
default:
break;
}
return success();
}
Result HuagaoDs::imageLayoutGet(const Identity&, ImageLayout& data) {
// our image does not change
auto dib = header();
data.setDocumentNumber(1);
data.setFrameNumber(1);
data.setPageNumber(1);
data.setFrame(Frame(0, 0, static_cast<float>(dib->biWidth) / m_scanparam->resolution_dst, static_cast<float>(dib->biHeight) / m_scanparam->resolution_dst));
return success();
}
Result HuagaoDs::imageLayoutGetDefault(const Identity& origin, ImageLayout& data) {
return imageLayoutGet(origin, data);
}
Result HuagaoDs::imageLayoutSet(const Identity& origin, ImageLayout& lay) {
// we dont support setting image frame
ImageLayout def;
imageLayoutGetDefault(origin, def);
return lay.frame() == def.frame() ? success() : badValue();
}
Result HuagaoDs::imageLayoutReset(const Identity& origin, ImageLayout& data) {
return imageLayoutGet(origin, data);
}
static int xtfer = 0;
Result HuagaoDs::imageMemXferGet(const Identity& origin, ImageMemXfer& data) {
if (!m_pendingXfers) {
FileTools::writelog(log_INFO, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>ͼƬ ===> Twain imageNativeXferGet m_pendingXfers ");
return seqError();
}
// we can call our TWPP methods, but be careful about states
SetupMemXfer setup;
setupMemXferGet(origin, setup);
// just a simple stored BMP image
auto dib = header();
auto bpl = bytesPerLine();
auto memSize = data.memory().size();
FileTools::writelog(log_INFO, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>ͼƬ ===> Twain imageNativeXferGet size error setup.maxsize = " + to_string(setup.maxSize()) +" setup.minsize "+ to_string(setup.minSize()));
if (memSize > setup.maxSize() || memSize < setup.minSize()) {
FileTools::writelog(log_INFO, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>ͼƬ ===> Twain imageNativeXferGet size error data.size = "+to_string(memSize) );
return badValue();
}
auto maxRows = memSize / bpl;
auto rows = std::min<UInt32>(maxRows, static_cast<UInt32>(dib->biHeight) - m_memXferYOff);
if (rows == 0) {
FileTools::writelog(log_INFO, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>ͼƬ ===> Twain imageNativeXferGet rows == 0");
return seqError(); // image already transfered in this session
}
cv::Mat mat;
vector<uchar> cmpdata;
if (m_compression == Compression::Group4)
{
mat = cv::imdecode(*bmpData.get(), cv::IMREAD_GRAYSCALE);
G4Tiff gt(mat, G4Tiff::Mode::MemoryMode, "", 120, m_scanparam->resolution_dst);
gt.GetCompressedData(cmpdata);
}
data.setBytesPerRow(bpl);
data.setColumns(static_cast<UInt32>(dib->biWidth));
data.setRows(rows);
data.setBytesWritten(m_compression == Compression::None ? bpl * rows : cmpdata.size());
data.setXOffset(0);
data.setYOffset(m_memXferYOff);
data.setCompression(m_compression);
auto lock = data.memory().data();
char* out = lock.data();
auto bmpsize = bmpData->size();
// bottom-up BMP -> top-down memory transfer
if (m_compression == Compression::None)
{
auto begin = bmpEnd() - (bpl * (m_memXferYOff + 1));
for (UInt32 i = 0; i < rows; i++) {
// copy bytes
std::copy(begin, begin + bpl, out);
char* line = out;
out += bpl;
begin -= bpl;
if (dib->biBitCount == 24)
{
//BGR BMP -> RGB memory transfer
for (; line + 3 < out; line += 3) {
std::swap(line[0], line[2]);
}
}
}
}
else
{
std::copy(cmpdata.data(), cmpdata.data() + cmpdata.size(), out);
}
m_memXferYOff += rows;
if (m_memXferYOff >= static_cast<UInt32>(std::abs(dib->biHeight))) {
m_pendingXfers = 0;
m_memXferYOff = 0;
//bmpData.reset(new std::vector<unsigned char>);
FileTools::writelog(log_INFO, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>ͼƬ ===> Twain imageNativeXferGet m_memXferYOff transfered num of " + to_string(++xtfer) + " images");
return { ReturnCode::XferDone, ConditionCode::Success };
}
FileTools::writelog(log_INFO, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>ͼƬ ===> Twain imageNativeXferGet transfered num of " + to_string(++xtfer) + " images");
return success();
}
Result HuagaoDs::imageNativeXferGet(const Identity& id, ImageNativeXfer& data) {
if (!m_pendingXfers) {
return seqError();
}
if (m_haveError)
return { ReturnCode::Cancel, ConditionCode::Success };
if (data)
data.release();
// it does not get easier than that if we already have BMP
data = ImageNativeXfer(bmpSize());
std::copy(bmpBegin(), bmpEnd(), data.data<char>().data());
//bmpData.reset(new std::vector<unsigned char>);
//FileTools::write_log("<22><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>ͼƬ ===> Twain transfered num of " + to_string(++xtfer) + " images");
FileTools::writelog(log_INFO, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>ͼƬ ===> Twain transfered num of " + to_string(++xtfer) + " images");
return { ReturnCode::XferDone, ConditionCode::Success };
}
Twpp::Result HuagaoDs::pendingXfersStopFeeder(const Identity& origin, PendingXfers& data)
{
if (!scanner.get())
return seqError();
if (scanner->IsConnected()) {
scanner->Stop_scan();
}
data.setCount(scanner->Get_IsImageQueueEmpty() ? 0 : 1);
return success();
}
Twpp::Result HuagaoDs::setupFileXferGet(const Twpp::Identity& origin, Twpp::SetupFileXfer& data)
{
data.setFilePath(m_fileXfer.filePath());
data.setFormat(m_fileXfer.format());
return success();
}
Twpp::Result HuagaoDs::setupFileXferGetDefault(const Twpp::Identity& origin, Twpp::SetupFileXfer& data)
{
Str255 str("HGTwain.bmp");
data.setFilePath(str);
data.setFormat(ImageFileFormat::Bmp);
return success();
}
Twpp::Result HuagaoDs::setupFileXferSet(const Twpp::Identity& origin, Twpp::SetupFileXfer& data)
{
m_fileXfer.setFilePath(data.filePath());
m_fileXfer.setFormat(data.format());
return success();
}
Twpp::Result HuagaoDs::setupFileXferReset(const Twpp::Identity& origin, Twpp::SetupFileXfer& data)
{
m_fileXfer.setFormat(Twpp::ImageFileFormat::Bmp);
std::string templateName = "HG";
char* tempPath = mktemp((char*)templateName.c_str());
if (tempPath) {
Str255 str;
str.setData(tempPath, strlen(tempPath));
m_fileXfer.setFilePath(str);
return success();
}
return badProtocol();
}
static int indeximg = 0;
Twpp::Result HuagaoDs::imageFileXferGet(const Twpp::Identity& origin)
{
if (!m_pendingXfers)
return seqError();
string filename = m_fileXfer.filePath().string();
switch (m_fileXfer.format())
{
case ImageFileFormat::Bmp: {
FILE* pfile = fopen(filename.c_str(), "wb");
if (pfile) {
if (bmpData->size() > 0) {
fwrite(bmpData->data(), 1, bmpData->size(), pfile);
bmpData.reset(new std::vector<unsigned char>);
fclose(pfile);
return Result(ReturnCode::XferDone, ConditionCode::Success);
}
}
return Result(ReturnCode::Failure, ConditionCode::BadValue);
}
case ImageFileFormat::Tiff:
case ImageFileFormat::Jfif: {
BITMAPINFOHEADER& bmpinfo = *((BITMAPINFOHEADER*)header());
int decodetype;
if (bmpinfo.biBitCount == 24)
decodetype = cv::IMREAD_COLOR;
else
decodetype = cv::IMREAD_GRAYSCALE;
cv::Mat ims = cv::imdecode(*bmpData.get(), decodetype);
if (m_compression == Compression::Group4 && m_fileXfer.format() == ImageFileFormat::Tiff)
{
if (!ims.empty() && ims.channels() == 3)
cvtColor(ims, ims, cv::COLOR_BGR2GRAY);
G4Tiff gsave(ims, G4Tiff::Mode::FileMode, filename, 120, m_scanparam->resolution_dst);
gsave.SaveG4Tiff();
}
else
{
std::vector<int> compression_params;
compression_params.push_back(CV_IMWRITE_JPEG_QUALITY);
compression_params.push_back(m_jpegQuality);
std::vector<uchar> imgdate;
cv::imencode(".jpg", ims, imgdate, compression_params);
std::ofstream out(filename,std::ios::binary | std::ios::out | std::ios::trunc);
if (out.is_open())
out.write((const char*)imgdate.data(), imgdate.size()),out.close();
//cv::imwrite(filename, ims, compression_params);
}
bmpData.reset(new std::vector<unsigned char>);
ims.release();
return Result(ReturnCode::XferDone, ConditionCode::Success);
}
default:
break;
}
return badProtocol();
}
Twpp::Result HuagaoDs::showTwainUI(Twpp::UserInterface& ui, bool bUiOnly)
{
// as a minimal source, we do not support GUI that just saves settings
if (ui.parent()) {
guiBridge.reset(new CDialog());
HWND appWindow = static_cast<HWND>(ui.parent().raw());
guiBridge->Create(IDD_BACK, CWnd::FromHandle(appWindow));
HWND bridgeWindow = guiBridge->GetSafeHwnd();
long bridgeFlags = GetWindowLong(bridgeWindow, GWL_STYLE);
SetWindowLong(bridgeWindow, GWL_STYLE, bridgeFlags | WS_CHILD);
SetParent(bridgeWindow, appWindow);
}
//!< show ui to scan button push
auto scanFunction = [this](const GScanCap& caps) {
if (!scanner->IsConnected())
{
scanner->open(vid, pid);
if (!scanner->IsConnected())
return checkDeviceOnline();
}
#ifndef G200
if (typeid(*scanner.get()) != typeid(GScanO1003399)) {
while (!scanner->Get_Scanner_PaperOn())
{
if (MessageBox(NULL, L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><EFBFBD>", L"<EFBFBD><EFBFBD>ʾ", MB_YESNO | MB_SYSTEMMODAL) == IDNO) {
m_pendingXfers = 0;
return seqError();
}
}
}
#endif // !G200
m_pendingXfers = 1;
m_scanparam.reset(new GScanCap(caps));
saveGscanCapSetting();
if (!scanner->IsConnected())
{
MessageBox(NULL, L"USB<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>USB<53><42><EFBFBD><EFBFBD><EFBFBD>´<EFBFBD><C2B4><EFBFBD>ɨ<EFBFBD><C9A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", L"<EFBFBD><EFBFBD>ʾ", MB_OK | MB_SYSTEMMODAL);
return seqError();
}
if (startScan() == success()) {
notifyXferReady();
}
else {
m_pendingXfers = 0;
}
};
//!< ui only to confirm button push
auto confirmFunction = [this](const GScanCap& caps) {
m_scanparam.reset(new GScanCap(caps));
saveGscanCapSetting();
notifyCloseOk();
};
//!< cancel button push
auto cancelFunction = [this]() {
//if (m_modal)
//{
// ::EnableWindow(parent, true);
//}
notifyCloseCancel();
};
CWnd* parent = guiBridge.get();
TwGlue glue = { scanFunction, cancelFunction };
TwGlue glueUiOnly = { confirmFunction, cancelFunction };
std::string serialnum = scanner->GetSerialNum();
std::string hardwareversion = scanner->GetFWVersion();
std::string macadder = scanner->GetMacAdder();
uint32_t mbversion = scanner->GetMotorFPGA();
guiTwain.reset(new CTwainUI(bUiOnly ? glueUiOnly : glue, *m_scanparam, bUiOnly ? "ȷ<EFBFBD><EFBFBD>" : "ɨ<EFBFBD><EFBFBD>", hardwareversion, serialnum,macadder,mbversion));
guiTwain->Create(IDD_TWAINUI, parent);
CRect newRect;
::GetWindowRect(static_cast<HWND>(ui.parent().raw()), &newRect);
if (newRect.top <= 0 || newRect.left <= 0)
newRect.top = newRect.left = 20;
SetWindowPos(guiTwain->m_hWnd, HWND_TOP, newRect.left + 20, newRect.top + 100, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOACTIVATE);
//SetWindowPos(guiTwain->m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE);
guiTwain->ShowWindow(SW_SHOWNORMAL);
return success();
}
void HuagaoDs::DeviceEvent_callback(int eventID, void* usrdata)
{
HuagaoDs* This = (HuagaoDs*)usrdata;
This->onDeviceEvent(eventID);
}
void HuagaoDs::CapabilityPrintf(Twpp::Msg msg, std::string capability, std::string value)
{
if (!is_printfcapability)
return;
switch (msg)
{
case Msg::Reset:
FileTools::writelog(log_INFO, (std::string)enum2str(Msg::Reset) + "\t" + capability);
break;
case Msg::Get:
FileTools::writelog(log_INFO, (std::string)enum2str(Msg::Get) + "\t" + capability);
break;
case Msg::GetCurrent:
FileTools::writelog(log_INFO, (std::string)enum2str(Msg::GetCurrent) + "\t" + capability);
break;
case Msg::GetDefault:
FileTools::writelog(log_INFO, (std::string)enum2str(Msg::GetDefault) + "\t" + capability);
break;
case Msg::Set:
FileTools::writelog(log_INFO, (std::string)enum2str(Msg::Set) + "\t" + capability+"\t value = "+value);
break;
default:
break;
}
}
void HuagaoDs::onDeviceEvent(int eventID)
{
//if (mapDeviceEvent.count(eventID))
//{
// DeviceEvent::Type dev_type = mapDeviceEvent[eventID];
// auto evt = DeviceEvent::simple((DeviceEvent::Type)dev_type, "HuaGo Device Event");
// devEvent.push(evt);
// notifyDeviceEvent();
//}
}
const BITMAPINFOHEADER* HuagaoDs::header() const noexcept {
return reinterpret_cast<const BITMAPINFOHEADER*>(bmpData->data() + sizeof(BITMAPFILEHEADER));
}
UInt32 HuagaoDs::bytesPerLine() const noexcept {
auto dib = header();
return static_cast<UInt32>(dib->biWidth * dib->biBitCount + 31) / 32 * 4;
}
UInt32 HuagaoDs::bmpSize() const noexcept {
return static_cast<UInt32>(bmpData->size()) - sizeof(BITMAPFILEHEADER);
}
const char* HuagaoDs::bmpBegin() const noexcept {
return (const char*)bmpData->cbegin()._Ptr + sizeof(BITMAPFILEHEADER);
}
const char* HuagaoDs::bmpEnd() const noexcept {
return (const char*)bmpData->cend()._Ptr;
}
void HuagaoDs::updataGscanCap()
{
GscanJsonConfig js;
GScanCap cfs = js.ReadGscanCap();
cfs.resolution_native = 200.0f;
cfs.threshold = 128;
if (cfs.is_autocrop)
{
m_autoboarderdetcet = true;
m_autosize = (UInt16)AutoSize::Auto;
}
m_scanparam.reset(new GScanCap(cfs));
}
Twpp::Result HuagaoDs::startScan()
{
xtfer = 0;
//if (!scanner->IsConnected())
//{
// scanner->open(vid, pid);
// if (!scanner->IsConnected())
// return checkDeviceOnline();
//}
bmpData.reset(new std::vector<unsigned char>());
scanner->ResetScanner();
scanner->reset();
FileTools::writelog(log_INFO, "start scan");
#ifdef G200
scanner->clear_hwerror();
#else
#ifndef ANDROIDSERIAL
if (scanner->notifyscan() < 1)
return seqError();
#endif // !ANDROIDSERIAL
#endif //
#ifdef G200
if (scanner->Get_Roller_num() > 450000)
#elif defined G300
if (scanner->Get_Roller_num() > 150000)
#else
if (scanner->Get_Roller_num() > 200000)
#endif // G200
{
Twain_config config;
if (config.getrollermsgdate() < chrono::duration_cast<chrono::duration<int, ratio<24 * 60 * 60>>>(chrono::system_clock::now().time_since_epoch()).count()){
hgmsg(_T("ֽ<EFBFBD>ִ<EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>÷<EFBFBD>Χ<EFBFBD><EFBFBD>ɨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD>ֽʧ<EFBFBD>ܡ<EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ŵ<EFBFBD><EFBFBD>쳣Ƶ<EFBFBD>ο<EFBFBD><EFBFBD>ܻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD>⼰ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD>̹<EFBFBD><EFBFBD><EFBFBD><EFBFBD>滻ֽ<EFBFBD>֣<EFBFBD>"));
config.setrollermsgdata(chrono::duration_cast<chrono::duration<int, ratio<24 * 60 * 60>>>(chrono::system_clock::now().time_since_epoch()).count());
}
}
//m_scanparam->brightness =300; // <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> 500 - 142
//m_scanparam->contrast = 0; // С<><D0A1>ר<EFBFBD><D7A8>
scanner->config_params(*m_scanparam);
std::string info = "papertype= " + to_string(m_scanparam->papertype) +
"\nAutoCrop_threshold= " + to_string(m_scanparam->AutoCrop_threshold) +
"\nautodescrew = " + to_string(m_scanparam->autodescrew) +
"\nautomaticcolor= " + to_string(m_scanparam->automaticcolor) +
"\nbrightness = " + to_string(m_scanparam->brightness) +
"\ncontrast = " + to_string(m_scanparam->contrast) +
"\nis_detachnoise = " + to_string(m_scanparam->detachnoise.is_detachnoise) +
"\ndetachnoise = " + to_string(m_scanparam->detachnoise.detachnoise) +
"\nen_fold = " + to_string(m_scanparam->en_fold) +
"\nen_sizecheck = " + to_string(m_scanparam->en_sizecheck) +
"\nenhance_color = " + to_string(m_scanparam->enhance_color) +
"\nfillbackground = " + to_string(m_scanparam->fillbackground) +
"\nfilter = " + to_string(m_scanparam->filter) +
"\nis_fillhole = " + to_string(m_scanparam->fillhole.is_fillhole) +
"\ngamma = " + to_string(m_scanparam->gamma) +
"\ncapturepixtype = " + to_string(m_scanparam->hardwarecaps.capturepixtype) +
"\nen_doublefeed = " + to_string(m_scanparam->hardwarecaps.en_doublefeed) +
"\nhsvcorrect = " + to_string(m_scanparam->hsvcorrect) +
"\nimageRotateDegree = " + to_string(m_scanparam->imageRotateDegree) +
"\nindent = " + to_string(m_scanparam->indent) +
"\nis_autocontrast = " + to_string(m_scanparam->is_autocontrast) +
"\nis_autocrop = " + to_string(m_scanparam->is_autocrop) +
"\nis_autocontrast = " + to_string(m_scanparam->is_autocontrast) +
"\nis_autodiscradblank_normal = " + to_string(m_scanparam->is_autodiscradblank_normal) +
"\nis_autodiscradblank_vince = " + to_string(m_scanparam->is_autodiscradblank_vince) +
"\nis_autotext = " + to_string(m_scanparam->is_autotext) +
"\nis_convex = " + to_string(m_scanparam->is_convex) +
"\nis_duplex = " + to_string(m_scanparam->is_duplex) +
"\nis_switchfrontback = " + to_string(m_scanparam->is_switchfrontback) +
"\nis_dogeardetection = " + to_string(m_scanparam->is_dogeardetection) +
"\nmulti_output_red = " + to_string(m_scanparam->multi_output_red) +
"\nen_multi_output = " + to_string(m_scanparam->en_multi_output) +
"\nmultioutput = " + to_string(m_scanparam->multioutput) +
"\nnoise = " + to_string(m_scanparam->noise) +
"\npaperAlign = " + to_string(m_scanparam->paperAlign) +
"\npixtype = " + to_string(m_scanparam->pixtype) +
"\nresolution_dst = " + to_string(m_scanparam->resolution_dst) +
"\nscannum = " + to_string(m_scanparam->scannum) +
"\nsharpen = " + to_string(m_scanparam->sharpen);
FileTools::writelog(log_TRACE,info);
scanner->UpdateScanInfo(0, 0);
scanner->Scanner_StartScan(m_scanparam->scannum);
if (bmpData->size() > 0)
{
bmpData.reset(new std::vector<unsigned char>);
}
if (guiTwain.get()) {
((CTwainUI*)(guiTwain.get()))->EnableID_OKorID_Cancel(false);
}
int retCode = scanner->aquire_bmpdata(*bmpData.get());
if (retCode == 0)
{
if (m_bIndicator) {
//!< cancel button push
auto stopFunc = [this]() {
if (scanner.get())
scanner->Stop_scan();
//guiIndicator.reset();//ȡ<><C8A1>ɨ<EFBFBD><C9A8> <20>رս<D8B1><D5BD><EFBFBD>ָʾ<D6B8><CABE>
//if (guiTwain.get()) {
// ((CTwainUI*)(guiTwain.get()))->EnableID_OKorID_Cancel(true);
//}
onDeviceEvent(USER_STOP);
};
guiIndicator = new CIndicatorDlg(stopFunc);
scanner->regist_indicatortext_callback([this](int aquire, int updata)
{ if (guiIndicator->GetSafeHwnd())
guiIndicator->setindicatortext(aquire, updata);
},
[this](CString str)
{ if (guiIndicator->GetSafeHwnd())
guiIndicator->setindicatortext(str);
});
guiIndicator->Create(IDD_INDICATOR, guiTwain.get() ? guiTwain.get() : guiBridge.get());//guiTwain ? guiTwain.get() : guiBridge.get()
guiIndicator->ShowWindow(SW_SHOWNORMAL);
}
}
if (retCode != 0) {
scanner->Set_ErrorCode(0);
if (guiIndicator->GetSafeHwnd())
guiIndicator->DestroyWindow();
//if(guiIndicator.get())
// guiIndicator.reset();
if (retCode != -1) {
CString str;
str.Format(_T("%d"), retCode);
m_pendingXfers = 0;
m_memXferYOff = 0;
m_haveError = true;
//ShellExecute(guiTwain ? guiTwain->m_hWnd : NULL, TEXT("open"), GetHidedlgPath(), str, NULL, SW_HIDE);
int index = scanner->geterrorindex();
if (retCode == 82 && ((typeid(*scanner.get()) == typeid(GScanO1003399))))
showmsg("<EFBFBD><EFBFBD>ʾ", "<EFBFBD>ڵ<EFBFBD>" + to_string(index) + "ҳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>۽ǣ<EFBFBD>ֹͣɨ<EFBFBD>", retCode);
else if (retCode == 75 && ((typeid(*scanner.get()) == typeid(GScanO1003399))))
showmsg("<EFBFBD><EFBFBD>ʾ", "<EFBFBD>ڵ<EFBFBD>" + to_string(index) + "ҳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֹͣɨ<EFBFBD>", retCode);
else if (retCode == 81 && ((typeid(*scanner.get()) == typeid(GScanO1003399))))
showmsg("<EFBFBD><EFBFBD>ʾ", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", retCode);
else
showmsg("<EFBFBD><EFBFBD>ʾ", msgs[(UsbSupported)retCode], retCode);
FileTools::writelog(log_ERROR, msgs[(UsbSupported)retCode]);
#ifndef G200
scanner->clear_hwerror();
#endif //
}
if (guiTwain.get()) {
((CTwainUI*)(guiTwain.get()))->EnableID_OKorID_Cancel(true);
}
if (retCode == 2)
return { ReturnCode::Failure, ConditionCode::NoMedia };//<2F><>ֽ
return seqError();
}
if (bmpData->size() > 0) {
m_haveError = false;
return success();
}
else {
if (guiTwain.get()) {
((CTwainUI*)(guiTwain.get()))->EnableID_OKorID_Cancel(true);
}
return seqError();
}
}
void HuagaoDs::saveGscanCapSetting()
{
TCHAR szIniFile[MAX_PATH] = { 0 };
SHGetSpecialFolderPath(NULL, szIniFile, CSIDL_LOCAL_APPDATA, TRUE);
_tcscat(szIniFile, HUAGAO_SCAN);
_tcscat(szIniFile, TWAIN_INIPATH);
_tcscat(szIniFile, TEXT("\\"));
_tcscat(szIniFile, TWAIN_JSON_NAME);
GscanJsonConfig js;
//vector<GScanCap> vc;
//vc.push_back(*m_scanparam);
std::string savepath = TCHAR2STRING(szIniFile);
js.SaveGscancapJson(*m_scanparam, savepath);
//js.WriteJsonArrayToFile(vc, savepath);
}