2020-03-11 01:58:06 +00:00
|
|
|
|
#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 "Device/PublicFunc.h"
|
|
|
|
|
#include "Device/GScanO200.h"
|
|
|
|
|
#include "Device/filetools.h"
|
|
|
|
|
#include "Device/GScanVirtual.h"
|
|
|
|
|
#include <list>
|
|
|
|
|
#include <map>
|
2020-06-20 03:01:35 +00:00
|
|
|
|
#include <opencv2/opencv.hpp>
|
|
|
|
|
#include "GscanJsonConfig.h"
|
2020-08-31 07:44:24 +00:00
|
|
|
|
#include "G4Tiff.h"
|
|
|
|
|
|
2020-03-11 01:58:06 +00:00
|
|
|
|
//custom define caps enum
|
|
|
|
|
enum class CapTypeEx : unsigned short {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
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_DBAreaNum = 0x8027,
|
|
|
|
|
TwEx_DBDevnMax = 0x8028,
|
|
|
|
|
TwEx_StableDetectEnable = 0x8090,
|
|
|
|
|
TwEx_UVModel = 0x8093,
|
2020-06-23 09:31:43 +00:00
|
|
|
|
TwEx_SwitchFrontBack = 0x8094,
|
2020-11-16 10:05:04 +00:00
|
|
|
|
TwEx_HsvCorrect = 0x8095,
|
|
|
|
|
TwEx_DogEarDelection=0x8096,
|
2020-03-11 01:58:06 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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(
|
2020-07-20 02:29:10 +00:00
|
|
|
|
Version(3, 3, Language::English, Country::China, "v3.3.2.4"),
|
2020-06-20 03:01:35 +00:00
|
|
|
|
DataGroup::Image,
|
2020-07-20 02:29:10 +00:00
|
|
|
|
#ifdef MAKEHUAGAO
|
2020-06-20 03:01:35 +00:00
|
|
|
|
"HUAGO",
|
2020-11-16 10:05:04 +00:00
|
|
|
|
#elif defined LANXUM
|
|
|
|
|
"LANXUM",
|
2020-07-20 02:29:10 +00:00
|
|
|
|
#else // MAKEHUAGAO
|
|
|
|
|
"ZHIBEN",
|
2020-06-20 03:01:35 +00:00
|
|
|
|
#endif
|
2020-07-20 02:29:10 +00:00
|
|
|
|
|
|
|
|
|
#ifdef G200
|
|
|
|
|
#ifdef ISG100
|
|
|
|
|
"G100 Series",
|
|
|
|
|
#else // ISG100
|
|
|
|
|
"G200 Series",
|
|
|
|
|
#endif
|
2020-06-20 03:01:35 +00:00
|
|
|
|
#elif defined(G300) // G200
|
2020-11-16 10:05:04 +00:00
|
|
|
|
#ifdef LANXUM
|
|
|
|
|
"G4260F Series",
|
|
|
|
|
#else // ISG100
|
|
|
|
|
"G300 Series",
|
|
|
|
|
#endif
|
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
#elif defined(G400) // G200
|
|
|
|
|
"G400 Series",
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef G200
|
2020-07-20 02:29:10 +00:00
|
|
|
|
#ifdef ISG100
|
|
|
|
|
#ifndef MAKEHUAGAO
|
|
|
|
|
"ZhibenScan G100 TWAIN"
|
|
|
|
|
#else // !MAKEHUAGAO
|
|
|
|
|
"HUAGOSCAN G100 TWAIN"
|
|
|
|
|
#endif
|
|
|
|
|
#else // ISG100
|
|
|
|
|
#ifndef MAKEHUAGAO
|
|
|
|
|
"ZhibenScan G200 TWAIN"
|
|
|
|
|
#else // !MAKEHUAGAO
|
|
|
|
|
"HUAGOSCAN G200 TWAIN"
|
|
|
|
|
#endif
|
2020-06-20 03:01:35 +00:00
|
|
|
|
#endif
|
2020-11-16 10:05:04 +00:00
|
|
|
|
#elif defined G300 // G200
|
|
|
|
|
#ifdef MAKEHUAGAO
|
2020-07-20 02:29:10 +00:00
|
|
|
|
"HUAGOSCAN G300 TWAIN"
|
2020-11-16 10:05:04 +00:00
|
|
|
|
#elif defined LANXUM //!LANXUM
|
|
|
|
|
"LANXUM G4260F TWAIN"
|
|
|
|
|
#else // !MAKEHUAGAO
|
|
|
|
|
"ZhibenScan G300 TWAIN"
|
2020-07-20 02:29:10 +00:00
|
|
|
|
#endif
|
2020-06-20 03:01:35 +00:00
|
|
|
|
#elif defined(G400) // G200
|
2020-07-20 02:29:10 +00:00
|
|
|
|
#ifndef MAKEHUAGAO
|
|
|
|
|
"ZhibenScan G400 TWAIN"
|
|
|
|
|
#else // !MAKEHUAGAO
|
|
|
|
|
"HUAGOSCAN G400 TWAIN"
|
|
|
|
|
#endif
|
2020-06-20 03:01:35 +00:00
|
|
|
|
#endif
|
2020-07-20 02:29:10 +00:00
|
|
|
|
|
2020-03-11 01:58:06 +00:00
|
|
|
|
#if defined(_MSC_VER)
|
2020-06-20 03:01:35 +00:00
|
|
|
|
""
|
2020-03-11 01:58:06 +00:00
|
|
|
|
#elif defined(__GNUC__)
|
2020-06-20 03:01:35 +00:00
|
|
|
|
" GCC"
|
2020-03-11 01:58:06 +00:00
|
|
|
|
#elif defined(__clang__)
|
2020-06-20 03:01:35 +00:00
|
|
|
|
" CLang"
|
2020-03-11 01:58:06 +00:00
|
|
|
|
#endif
|
2020-06-20 03:01:35 +00:00
|
|
|
|
);
|
2020-03-11 01:58:06 +00:00
|
|
|
|
|
|
|
|
|
// lets just simulate uniform resolution for both axes
|
|
|
|
|
static constexpr UInt32 RESOLUTIONX = 85;
|
|
|
|
|
|
2020-08-15 08:42:43 +00:00
|
|
|
|
//static std::unique_ptr<CWinApp> application(new CWinApp());
|
2020-03-11 01:58:06 +00:00
|
|
|
|
|
2020-11-16 10:05:04 +00:00
|
|
|
|
static list<float> resList = { 100.0,150.0,200.0,240.0,300.0,600.0 };
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>G200 G300<30><30>G400ֽ<30>ŷ<EFBFBD><C5B7><EFBFBD>
|
|
|
|
|
#ifdef G200
|
2020-03-11 01:58:06 +00:00
|
|
|
|
|
|
|
|
|
static list<UInt16> paperSizeList = { (UInt16)PaperSize::A3,(UInt16)PaperSize::A4,(UInt16)PaperSize::A5,(UInt16)PaperSize::A6,
|
2020-06-20 03:01:35 +00:00
|
|
|
|
(UInt16)PaperSize::IsoB4,(UInt16)PaperSize::IsoB5,(UInt16)PaperSize::IsoB6,
|
|
|
|
|
(UInt16)PaperSize::UsLetter,(UInt16)PaperSize::UsLegal,(UInt16)PaperSize::UsLedger,
|
2020-11-16 10:05:04 +00:00
|
|
|
|
(UInt16)PaperSize::MaxSize,(UInt16)PaperSize::None,(UInt16)PaperSize::UsStatement };
|
2020-03-11 01:58:06 +00:00
|
|
|
|
|
2020-11-16 10:05:04 +00:00
|
|
|
|
#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 };
|
|
|
|
|
#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 };
|
|
|
|
|
#endif // G200
|
2020-05-16 01:59:44 +00:00
|
|
|
|
static list<float> imageRotateList = { 0.0,90.0,180.0,270.0 };
|
2020-03-11 01:58:06 +00:00
|
|
|
|
|
2020-08-31 07:44:24 +00:00
|
|
|
|
enum class DeviceEventType : UInt16
|
|
|
|
|
{
|
|
|
|
|
CustomEvents = 0x8000,
|
|
|
|
|
Dev_OPENCOVER,
|
|
|
|
|
Dev_NOFEED,
|
|
|
|
|
Dev_FEEDERROR,
|
|
|
|
|
Dev_STABLE,
|
|
|
|
|
Dev_SKREW,
|
|
|
|
|
Dev_COUNTMOE,
|
|
|
|
|
Dev_HARDWAREERROR,
|
|
|
|
|
Dev_FPGAERROR,
|
2020-11-16 10:05:04 +00:00
|
|
|
|
Dev_UserStop,
|
|
|
|
|
Dev_DogEar
|
2020-08-31 07:44:24 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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},
|
2020-11-16 10:05:04 +00:00
|
|
|
|
{USER_STOP,(DeviceEvent::Type)(DeviceEventType::Dev_UserStop)},
|
|
|
|
|
{DOG_EAR,(DeviceEvent::Type)(DeviceEventType::Dev_DogEar)}
|
2020-08-31 07:44:24 +00:00
|
|
|
|
};
|
2020-03-11 01:58:06 +00:00
|
|
|
|
|
|
|
|
|
static void DeleteWnd(CDialog* pWnd) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
if (pWnd && pWnd->GetSafeHwnd()) {
|
2020-08-31 07:44:24 +00:00
|
|
|
|
if(pWnd->m_hWnd)
|
|
|
|
|
DestroyWindow(pWnd->m_hWnd);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
}
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
2020-08-31 07:44:24 +00:00
|
|
|
|
static std::unique_ptr<CTwainUI, void(*)(CDialog*)> guiTwain(nullptr, DeleteWnd);
|
2020-03-11 01:58:06 +00:00
|
|
|
|
|
|
|
|
|
#if TWPP_DETAIL_OS_WIN
|
|
|
|
|
static std::unique_ptr<CDialog, void(*)(CDialog*)> guiBridge(nullptr, DeleteWnd);
|
2020-08-31 07:44:24 +00:00
|
|
|
|
|
2020-03-11 01:58:06 +00:00
|
|
|
|
#endif
|
2020-08-31 07:44:24 +00:00
|
|
|
|
//static std::unique_ptr<CIndicatorDlg, void(*)(CDialog*)> guiIndicator(nullptr, DeleteWnd);
|
|
|
|
|
static CIndicatorDlg* guiIndicator =NULL;
|
2020-07-11 10:43:17 +00:00
|
|
|
|
//#define HG_VIRTUAL
|
2020-03-11 01:58:06 +00:00
|
|
|
|
#ifndef HG_VIRTUAL
|
2020-08-31 07:44:24 +00:00
|
|
|
|
static std::unique_ptr<IScanner> scanner; //(new GScanO200());
|
2020-03-11 01:58:06 +00:00
|
|
|
|
#else
|
2020-06-20 03:01:35 +00:00
|
|
|
|
static std::unique_ptr<IScanner> scanner(new GScanVirtual());
|
2020-03-11 01:58:06 +00:00
|
|
|
|
#endif
|
|
|
|
|
HuagaoDs::HuagaoDs()
|
2020-06-20 03:01:35 +00:00
|
|
|
|
: m_scanparam(new GScanCap)
|
2020-11-16 10:05:04 +00:00
|
|
|
|
,bmpData(new std::vector<unsigned char>)
|
2020-06-20 03:01:35 +00:00
|
|
|
|
, hMutex(NULL)
|
2020-03-11 01:58:06 +00:00
|
|
|
|
{
|
2020-06-20 03:01:35 +00:00
|
|
|
|
/*string ss1= getOSInfo();
|
|
|
|
|
string ss2=getManufactureID();
|
|
|
|
|
string ss3=getCpuType();
|
|
|
|
|
string ss4= getMemoryInfo();
|
|
|
|
|
DWORD dwNum;
|
|
|
|
|
CString aas[10];
|
|
|
|
|
GetDiskInfo(dwNum,aas);*/
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HuagaoDs::~HuagaoDs()
|
|
|
|
|
{
|
2020-07-20 02:29:10 +00:00
|
|
|
|
if(scanner.get())
|
|
|
|
|
scanner.reset();
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
const Identity& HuagaoDs::defaultIdentity() noexcept {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
// remember, we return a reference, therefore the identity must not be placed on the stack of this method
|
|
|
|
|
return srcIdent;
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::call(const Identity& origin, DataGroup dg, Dat dat, Msg msg, void* data) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
try {
|
|
|
|
|
// we can override almost anything from SourceFromThis, even the top-most source instance call
|
|
|
|
|
return Base::call(origin, dg, dat, msg, data);
|
|
|
|
|
}
|
|
|
|
|
catch (const CapabilityException&) {
|
|
|
|
|
return badValue();
|
|
|
|
|
}
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-07-26 09:07:40 +00:00
|
|
|
|
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]));
|
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-11 01:58:06 +00:00
|
|
|
|
// some helper functions to handle capability stuff
|
|
|
|
|
template<typename T>
|
2020-05-16 01:59:44 +00:00
|
|
|
|
static Result oneValGet(Msg msg, Capability& data, const T& value) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
case Msg::GetDefault:
|
|
|
|
|
data = Capability::createOneValue(data.type(), value);
|
|
|
|
|
return {};
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return { ReturnCode::Failure, ConditionCode::CapBadOperation };
|
|
|
|
|
}
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static Result oneValGetString(Msg msg, Capability& data, std::string value) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
Str255 str;
|
|
|
|
|
str.setData(value.c_str(), value.size());
|
|
|
|
|
return oneValGet(msg, data, str);
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
2020-05-16 01:59:44 +00:00
|
|
|
|
static Result enmGet(Msg msg, Capability& data, const T& value) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
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 };
|
|
|
|
|
}
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
2020-05-16 01:59:44 +00:00
|
|
|
|
static Result oneValGetSet(Msg msg, Capability& data, T& value, const T& def) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
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 };
|
|
|
|
|
}
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
2020-05-16 01:59:44 +00:00
|
|
|
|
static Result oneValGetSetConst(Msg msg, Capability& data, const T& def) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
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 };
|
|
|
|
|
}
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
2020-05-16 01:59:44 +00:00
|
|
|
|
static Result enmGetSetConst(Msg msg, Capability& data, const T& def) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
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 };
|
|
|
|
|
}
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Shortcut for Result(RC::Failure, CC::CheckDeviceOnline).
|
|
|
|
|
static constexpr Result checkDeviceOnline() noexcept {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return { ReturnCode::Failure,ConditionCode::CheckDeviceOnline };
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::capCommon(const Identity&, Msg msg, Capability& data) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
auto it = m_caps.find(data.type());
|
|
|
|
|
if (it != m_caps.end()) {
|
|
|
|
|
return (it->second)(msg, data);
|
|
|
|
|
}
|
2020-03-11 01:58:06 +00:00
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return capUnsupported();
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::capabilityGet(const Identity& origin, Capability& data) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return capCommon(origin, Msg::Get, data);
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::capabilityGetCurrent(const Identity& origin, Capability& data) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return capCommon(origin, Msg::GetCurrent, data);
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::capabilityGetDefault(const Identity& origin, Capability& data) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return capCommon(origin, Msg::GetDefault, data);
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::capabilityQuerySupport(const Identity&, Capability& data) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
auto it = m_query.find(data.type());
|
|
|
|
|
MsgSupport sup = it != m_query.end() ? it->second : msgSupportEmpty;
|
|
|
|
|
data = Capability::createOneValue(data.type(), sup);
|
|
|
|
|
return success();
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::capabilityReset(const Identity& origin, Capability& data) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return capCommon(origin, Msg::Reset, data);
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::capabilityResetAll(const Identity& origin) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
for (auto& pair : m_query) {
|
|
|
|
|
if ((pair.second & MsgSupport::Reset) != msgSupportEmpty) {
|
|
|
|
|
Capability dummyCap(pair.first);
|
|
|
|
|
capCommon(origin, Msg::Reset, dummyCap);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return success();
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::capabilitySet(const Identity& origin, Capability& data) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return capCommon(origin, Msg::Set, data);
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::eventProcess(const Identity&, Event& event) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
// Qt needs to process its events, otherwise the GUI will appear frozen
|
|
|
|
|
// this is Windows-only method, Linux and macOS behave differently
|
|
|
|
|
if (guiTwain) {
|
|
|
|
|
// // QApplication::processEvents(); - TODO: needs more investigation; results in freeze when attempting to scan using old DSM
|
|
|
|
|
// QApplication::sendPostedEvents();
|
|
|
|
|
guiTwain->SendMessage((UINT)(event.message()));
|
|
|
|
|
}
|
|
|
|
|
event.setMessage(Msg::Null);
|
|
|
|
|
|
|
|
|
|
return { ReturnCode::NotDsEvent, ConditionCode::Success };
|
2020-05-16 01:59:44 +00:00
|
|
|
|
}
|
2020-08-15 08:42:43 +00:00
|
|
|
|
|
2020-08-31 07:44:24 +00:00
|
|
|
|
Twpp::Result HuagaoDs::deviceEventGet(const Twpp::Identity& origin, Twpp::DeviceEvent& data)
|
|
|
|
|
{
|
|
|
|
|
if (devEvent.size() > 0)
|
|
|
|
|
{
|
|
|
|
|
data = devEvent.front();
|
|
|
|
|
devEvent.pop();
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
return seqError();
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
//add------------------<2D><><EFBFBD><EFBFBD>jpgͼ<67><CDBC>dpi---------------------------
|
|
|
|
|
void HuagaoDs::SetResoluton(const char* path, int resolution)
|
|
|
|
|
{
|
2020-06-20 03:01:35 +00:00
|
|
|
|
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);
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-11-16 10:05:04 +00:00
|
|
|
|
void HuagaoDs::dogear_callback(int indexpaper)
|
|
|
|
|
{
|
|
|
|
|
CString text;
|
|
|
|
|
text.Format(_T("74 %d"), indexpaper);
|
|
|
|
|
ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), text, NULL, SW_HIDE);
|
|
|
|
|
scanner->Stop_scan();
|
|
|
|
|
//scanner->reset();
|
|
|
|
|
scanner->ResetScanner();
|
|
|
|
|
onDeviceEvent(DOG_EAR);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::identityOpenDs(const Identity&) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
//writelog("identityOpenDs");
|
2020-08-31 07:44:24 +00:00
|
|
|
|
if(!scanner.get())
|
|
|
|
|
scanner.reset(new GScanO200());
|
2020-11-16 10:05:04 +00:00
|
|
|
|
m_haveError = false;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
updataGscanCap();
|
2020-11-16 10:05:04 +00:00
|
|
|
|
bmpData->resize(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));
|
2020-06-20 03:01:35 +00:00
|
|
|
|
BITMAPINFOHEADER& bmInfo = *((BITMAPINFOHEADER*)header());
|
|
|
|
|
bmInfo.biHeight = 2000;
|
|
|
|
|
bmInfo.biWidth = 2000;
|
|
|
|
|
bmInfo.biBitCount = m_scanparam->pixtype == 2 ? 24 : (m_scanparam->pixtype == 1 ? 8 : 0);
|
|
|
|
|
m_iBitdepth = m_scanparam->pixtype == 2 ? 24 : (m_scanparam->pixtype == 1 ? 8 : 0);
|
2020-11-16 10:05:04 +00:00
|
|
|
|
#ifdef LANXUM
|
|
|
|
|
scanner->open(0x31c9, 0x8200);
|
|
|
|
|
#else
|
2020-06-20 03:01:35 +00:00
|
|
|
|
scanner->open(0x064B, 0x7823);
|
2020-11-16 10:05:04 +00:00
|
|
|
|
#endif
|
2020-07-11 10:43:17 +00:00
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
if (!scanner->IsConnected()) {
|
2020-07-07 01:54:19 +00:00
|
|
|
|
ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString("201"), NULL, SW_HIDE);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return checkDeviceOnline();
|
|
|
|
|
}
|
2020-08-31 07:44:24 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
scanner->regist_deviceevent_callback(DeviceEvent_callback, this);
|
2020-11-16 10:05:04 +00:00
|
|
|
|
scanner->DogEar_callback(std::bind(&HuagaoDs::dogear_callback, this, std::placeholders::_1));
|
2020-08-31 07:44:24 +00:00
|
|
|
|
}
|
2020-06-20 03:01:35 +00:00
|
|
|
|
hMutex = CreateMutex(NULL, FALSE, _T("LookitApp"));
|
|
|
|
|
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);
|
2020-07-07 01:54:19 +00:00
|
|
|
|
ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString("202"), NULL, SW_HIDE);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return seqError();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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) {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
case Msg::GetDefault: {
|
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
m_query[CapType::UiControllable] = msgSupportGetAll;
|
|
|
|
|
m_caps[CapType::UiControllable] = std::bind(enmGet<Bool>, _1, _2, Bool(true));
|
|
|
|
|
|
|
|
|
|
m_query[CapType::DeviceOnline] = msgSupportGetAll;
|
|
|
|
|
m_caps[CapType::DeviceOnline] = std::bind(enmGet<Bool>, _1, _2, Bool(scanner->IsConnected()));
|
|
|
|
|
|
|
|
|
|
m_query[CapType::XferCount] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[CapType::XferCount] = [this](Msg msg, Capability& data) -> Result {
|
|
|
|
|
if (msg == Msg::Set) {
|
|
|
|
|
auto item = data.currentItem<Int16>();
|
2020-08-31 07:44:24 +00:00
|
|
|
|
if (item > 65535 || item < -1||item == 0) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return badValue();
|
|
|
|
|
}
|
2020-08-15 08:42:43 +00:00
|
|
|
|
m_scanparam->scannum = item;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-15 08:42:43 +00:00
|
|
|
|
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;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return { ReturnCode::CheckStatus, ConditionCode::BadValue };
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
m_query[CapType::ICompression] = msgSupportGetAllSetReset;
|
2020-08-31 07:44:24 +00:00
|
|
|
|
//m_caps[CapType::ICompression] = std::bind(enmGetSetConst<Compression>, _1, _2, Compression::None);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
m_caps[CapType::ICompression] = [this](Msg msg, Capability& data)->Result
|
|
|
|
|
{
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
data = Capability::createEnumeration<CapType::ICompression>(
|
|
|
|
|
{ Compression::None, Compression::Group4 }, m_compression == Compression::None ? 0 : 1, 0);
|
|
|
|
|
return success();
|
|
|
|
|
// fallthrough
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<CapType::ICompression>(m_compression);
|
|
|
|
|
return success();
|
2020-07-11 10:43:17 +00:00
|
|
|
|
case Msg::Reset:
|
2020-06-20 03:01:35 +00:00
|
|
|
|
case Msg::GetDefault:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
m_compression = Compression::None;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data = Capability::createOneValue<CapType::ICompression>(Compression::None);
|
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<CapType::ICompression>();
|
|
|
|
|
if (Compression::None == mech || mech == Compression::Group4) {
|
|
|
|
|
m_compression = mech;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
return badValue();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
m_query[CapType::IBitDepth] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[CapType::IBitDepth] = [this](Msg msg, Capability& data) -> Result {
|
|
|
|
|
switch (msg)
|
|
|
|
|
{
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
data = Capability::createOneValue<CapType::IBitDepth>(UInt16(m_iBitdepth));
|
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::Reset:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
m_iBitdepth = 8;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data = Capability::createOneValue<CapType::IBitDepth>(UInt16(m_iBitdepth));
|
2020-08-31 07:44:24 +00:00
|
|
|
|
return success();
|
2020-06-20 03:01:35 +00:00
|
|
|
|
break;
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<CapType::IBitDepth>(UInt16(m_iBitdepth));
|
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::GetDefault:
|
2020-08-31 07:44:24 +00:00
|
|
|
|
data = Capability::createOneValue<CapType::IBitDepth>(24);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<CapType::IBitDepth>();
|
|
|
|
|
if (mech == 1 || mech == 8 || mech == 24)
|
|
|
|
|
{
|
|
|
|
|
m_iBitdepth = (UINT16)mech;
|
|
|
|
|
m_scanparam->pixtype = m_iBitdepth == 1 ? (int)PixelType::BlackWhite : (m_iBitdepth == 8 ? (int)PixelType::Gray : (int)PixelType::Rgb);
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
return badValue();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
m_query[CapType::IBitOrder] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[CapType::IBitOrder] = std::bind(enmGetSetConst<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;
|
2020-08-15 08:42:43 +00:00
|
|
|
|
m_caps[CapType::IPhysicalWidth] = std::bind(oneValGet<Fix32>, _1, _2, Fix32(static_cast<float>(header()->biWidth) / m_scanparam->resolution_dst));
|
2020-06-20 03:01:35 +00:00
|
|
|
|
|
|
|
|
|
m_query[CapType::IPhysicalHeight] = msgSupportGetAll;
|
2020-08-15 08:42:43 +00:00
|
|
|
|
m_caps[CapType::IPhysicalHeight] = std::bind(oneValGet<Fix32>, _1, _2, Fix32(static_cast<float>(header()->biHeight) / m_scanparam->resolution_dst));
|
2020-06-20 03:01:35 +00:00
|
|
|
|
|
|
|
|
|
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 {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
data = Capability::createEnumeration<CapType::IPixelType>(
|
|
|
|
|
{ PixelType::BlackWhite, PixelType::Gray, PixelType::Rgb }, (int)(m_scanparam->pixtype), (int)PixelType::Gray);
|
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<CapType::IPixelType>((PixelType)(m_scanparam->pixtype));
|
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::GetDefault:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
case Msg::Reset:
|
|
|
|
|
m_scanparam->pixtype = (byte)PixelType::Gray;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data = Capability::createOneValue<CapType::IPixelType>(PixelType::Gray);
|
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<CapType::IPixelType>();
|
|
|
|
|
if (mech == PixelType::Rgb || mech == PixelType::Gray || mech == PixelType::BlackWhite)
|
|
|
|
|
{
|
|
|
|
|
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>
|
2020-07-07 01:54:19 +00:00
|
|
|
|
//if (m_scanparam->pixtype == (int)PixelType::BlackWhite)
|
|
|
|
|
// m_scanparam->sharpen = SharpenBlur::Sharpen_None;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
}
|
|
|
|
|
m_iBitdepth = mech == PixelType::Rgb ? 24 : (mech == PixelType::Gray ? 8 : 1);
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
return badValue();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
//add------------------jpeg<65><67><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>---------------------
|
|
|
|
|
m_query[CapType::IJpegQuality] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[CapType::IJpegQuality] = [this](Msg msg, Capability& data)->Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<UInt16>(CapType::IJpegQuality, (UInt16)m_jpegQuality);
|
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::Reset:
|
|
|
|
|
case Msg::GetDefault:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
m_jpegQuality = 80;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data = Capability::createOneValue<UInt16>(CapType::IJpegQuality, 80);
|
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<CapType::IJpegQuality>();
|
|
|
|
|
if ((int)mech < 0 || (int)mech > 100)
|
2020-08-31 07:44:24 +00:00
|
|
|
|
return badValue();
|
2020-06-20 03:01:35 +00:00
|
|
|
|
m_jpegQuality = (int)mech;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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 {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
data = Capability::createEnumeration<CapType::IXferMech>(
|
|
|
|
|
{ XferMech::Native, XferMech::Memory, XferMech::File }, m_capXferMech == XferMech::Native ? 0 : (m_capXferMech == XferMech::Memory ? 1 : 2), 0);
|
|
|
|
|
return success();
|
|
|
|
|
// fallthrough
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<CapType::IXferMech>(m_capXferMech);
|
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::GetDefault:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
case Msg::Reset:
|
|
|
|
|
m_capXferMech = XferMech::Native;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data = Capability::createOneValue<CapType::IXferMech>(XferMech::Native);
|
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<CapType::IXferMech>();
|
|
|
|
|
if (mech == XferMech::Native || mech == XferMech::Memory || mech == XferMech::File) {
|
|
|
|
|
m_capXferMech = mech;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
return badValue();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
m_query[CapType::IXResolution] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[CapType::IXResolution] = [this](Msg msg, Capability& data) {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get: {
|
|
|
|
|
int index = -1;
|
|
|
|
|
std::list<float>::iterator it = resList.begin();
|
|
|
|
|
int i = 0;
|
|
|
|
|
for (it, i; it != resList.end(); ++it, i++) {
|
|
|
|
|
if (*it == m_scanparam->resolution_dst) {
|
|
|
|
|
index = i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
data = Capability::createEnumeration(data.type(), { Fix32(100.0),Fix32(150.0),Fix32(200.0),Fix32(240.0),Fix32(300.0) }, index == -1 ? 2 : index, 2);
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
case Msg::GetCurrent: {
|
|
|
|
|
data = Capability::createOneValue(data.type(), Fix32(m_scanparam->resolution_dst));
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
case Msg::GetDefault:
|
|
|
|
|
case Msg::Reset: {
|
2020-07-11 10:43:17 +00:00
|
|
|
|
m_scanparam->resolution_dst = 200.0f;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data = Capability::createOneValue(data.type(), Fix32(200.0));
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto res = data.currentItem<Fix32>();
|
|
|
|
|
std::list<float>::iterator resIter = resList.begin();
|
|
|
|
|
bool contains = false;
|
|
|
|
|
for (resIter; resIter != resList.end(); resIter++) {
|
|
|
|
|
if (*resIter == res) {
|
|
|
|
|
contains = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (contains) {
|
|
|
|
|
m_scanparam->resolution_dst = (float)res;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
return badValue();
|
|
|
|
|
}
|
|
|
|
|
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) {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get: {
|
|
|
|
|
int index = -1;
|
|
|
|
|
std::list<UInt16>::iterator it = paperSizeList.begin();
|
|
|
|
|
int i = 0;
|
|
|
|
|
for (it, i; it != paperSizeList.end(); ++it, i++) {
|
|
|
|
|
if (*it == m_scanparam->papertype) {
|
|
|
|
|
index = i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-11-16 10:05:04 +00:00
|
|
|
|
data = Capability::createEnumeration(data.type(), { (UInt16)PaperSize::A3,(UInt16)PaperSize::A4,(UInt16)PaperSize::A5,(UInt16)PaperSize::A6,
|
|
|
|
|
(UInt16)PaperSize::IsoB5,(UInt16)PaperSize::IsoB6,(UInt16)PaperSize::UsLetter,(UInt16)PaperSize::UsLegal,(UInt16)PaperSize::None
|
|
|
|
|
#ifndef G300
|
|
|
|
|
,(UInt16)PaperSize::UsLedger,(UInt16)PaperSize::IsoB4,
|
|
|
|
|
(UInt16)PaperSize::MaxSize,(UInt16)PaperSize::UsStatement
|
|
|
|
|
#endif //
|
|
|
|
|
},
|
2020-06-20 03:01:35 +00:00
|
|
|
|
index == -1 ? 0 : index,
|
|
|
|
|
0);
|
2020-11-12 11:42:16 +00:00
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue(data.type(), UInt16(m_scanparam->papertype));
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetDefault:
|
|
|
|
|
case Msg::Reset:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
m_scanparam->papertype =(int)PaperSize::A3;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data = Capability::createOneValue(data.type(), UInt16(PaperSize::A3));
|
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::Set: {
|
2020-07-11 10:43:17 +00:00
|
|
|
|
auto paper = data.currentItem<UInt16>();
|
2020-06-20 03:01:35 +00:00
|
|
|
|
std::list<UInt16>::iterator resIter = paperSizeList.begin();
|
|
|
|
|
bool contains = false;
|
|
|
|
|
for (resIter; resIter != paperSizeList.end(); resIter++) {
|
2020-07-11 10:43:17 +00:00
|
|
|
|
if (*resIter == paper) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
contains = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (contains) {
|
2020-07-11 10:43:17 +00:00
|
|
|
|
m_scanparam->papertype = (byte)paper;
|
2020-11-12 11:42:16 +00:00
|
|
|
|
if (paper == (byte)PaperSize::None|| paper == (byte)PaperSize::UsStatement)
|
2020-07-07 01:54:19 +00:00
|
|
|
|
m_scanparam->paperAlign = PaperAlign::Rot0;
|
2020-11-12 11:42:16 +00:00
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
return badValue();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
m_query[CapType::IOrientation] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[CapType::IOrientation] = [this](Msg msg, Capability& data) -> Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
data = Capability::createEnumeration<CapType::IOrientation>(
|
|
|
|
|
{ Orientation::Portrait, Orientation::Landscape }, m_scanparam->paperAlign, 0);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<CapType::IOrientation>((Orientation)(m_scanparam->paperAlign));
|
|
|
|
|
return success();
|
2020-07-11 10:43:17 +00:00
|
|
|
|
case Msg::Reset:
|
2020-06-20 03:01:35 +00:00
|
|
|
|
case Msg::GetDefault:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
m_scanparam->paperAlign = PaperAlign::Rot0;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data = Capability::createOneValue<CapType::IOrientation>(Orientation::Portrait);
|
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<CapType::IOrientation>();
|
|
|
|
|
if (mech == Orientation::Landscape || mech == Orientation::Portrait) {
|
|
|
|
|
m_scanparam->paperAlign = (PaperAlign)mech;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
return badValue();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
m_query[CapType::IRotation] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[CapType::IRotation] = [this](Msg msg, Capability& data) -> Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get: {
|
|
|
|
|
int index = -1;
|
|
|
|
|
std::list<float>::iterator it = imageRotateList.begin();
|
|
|
|
|
int i = 0;
|
|
|
|
|
for (it, i; it != imageRotateList.end(); ++it, i++) {
|
|
|
|
|
if ((m_scanparam->imageRotateDegree + 1) >= *it && (m_scanparam->imageRotateDegree - 1) <= *it) {
|
|
|
|
|
index = i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
data = Capability::createEnumeration<CapType::IRotation>(
|
2020-07-11 10:43:17 +00:00
|
|
|
|
{ Fix32(0.0f),Fix32(90.0f),Fix32(180.0f),Fix32(270.0f) },
|
2020-06-20 03:01:35 +00:00
|
|
|
|
index == -1 ? 0 : index,
|
|
|
|
|
0);
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<CapType::IRotation>(Fix32(m_scanparam->imageRotateDegree));
|
|
|
|
|
return success();
|
2020-07-11 10:43:17 +00:00
|
|
|
|
case Msg::Reset:
|
2020-06-20 03:01:35 +00:00
|
|
|
|
case Msg::GetDefault:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
m_scanparam->imageRotateDegree = 0.0f;
|
|
|
|
|
data = Capability::createOneValue<CapType::IRotation>(Fix32(0.0f));
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto res = data.currentItem<Fix32>();
|
|
|
|
|
std::list<float>::iterator resIter = imageRotateList.begin();
|
|
|
|
|
bool contains = false;
|
|
|
|
|
for (resIter; resIter != imageRotateList.end(); resIter++) {
|
|
|
|
|
if (((float)res + 1) >= *resIter && ((float)res - 1) <= *resIter) {
|
|
|
|
|
contains = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (contains) {
|
|
|
|
|
m_scanparam->imageRotateDegree = (float)res;
|
|
|
|
|
if (res != 0.0f)
|
|
|
|
|
m_scanparam->is_autotext = 0;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
return badValue();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
2020-03-11 01:58:06 +00:00
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
#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;
|
2020-09-21 01:25:46 +00:00
|
|
|
|
//m_caps[CapType::SerialNumber] = std::bind(oneValGetString, _1, _2, scanner->GetSerialNum());
|
|
|
|
|
m_caps[CapType::SerialNumber] = [this](Msg msg, Capability& data)->Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
case Msg::GetDefault:
|
|
|
|
|
{
|
|
|
|
|
std::string ser = scanner->GetSerialNum();
|
|
|
|
|
Str255 str;
|
|
|
|
|
str.setData(ser.c_str(), ser.size());
|
|
|
|
|
data = Capability::createOneValue<CapType::SerialNumber>(str);
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
|
|
|
|
|
m_query[(CapType)(CapTypeEx::TwEx_HardwareVersion)] = msgSupportGetAll;
|
2020-09-21 01:25:46 +00:00
|
|
|
|
//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 {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
case Msg::GetDefault:
|
|
|
|
|
{
|
|
|
|
|
std::string ser = scanner->GetFWVersion();
|
|
|
|
|
Str255 str;
|
|
|
|
|
str.setData(ser.c_str(), ser.size());
|
|
|
|
|
data = Capability::createOneValue<Str255>((CapType)(CapTypeEx::TwEx_HardwareVersion),str);
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
|
|
|
|
|
m_query[CapType::FeederLoaded] = msgSupportGetAll;
|
2020-08-31 07:44:24 +00:00
|
|
|
|
m_caps[CapType::FeederLoaded] = [this](Msg msg, Capability& data) -> Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
case Msg::GetDefault:
|
|
|
|
|
data = Capability::createOneValue<CapType::FeederLoaded>(Bool(scanner->Get_Scanner_PaperOn()));
|
|
|
|
|
return success();
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
2020-06-20 03:01:35 +00:00
|
|
|
|
|
|
|
|
|
m_query[CapType::Indicators] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[CapType::Indicators] = [this](Msg msg, Capability& data) -> Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
data = Capability::createEnumeration<CapType::Indicators>(
|
|
|
|
|
{ Bool(), Bool(true) }, Bool(m_bIndicator));
|
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
// fallthrough
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<CapType::Indicators>(m_bIndicator);
|
|
|
|
|
return success();
|
2020-07-11 10:43:17 +00:00
|
|
|
|
case Msg::Reset:
|
2020-06-20 03:01:35 +00:00
|
|
|
|
case Msg::GetDefault:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
m_bIndicator = true;
|
|
|
|
|
data = Capability::createOneValue<CapType::Indicators>(m_bIndicator);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto show = data.currentItem<CapType::Indicators>();
|
|
|
|
|
m_bIndicator = show;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
2020-07-26 09:07:40 +00:00
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
2020-06-20 03:01:35 +00:00
|
|
|
|
|
2020-07-26 09:07:40 +00:00
|
|
|
|
m_query[CapType::CustomDsData] = msgSupportGetAll;
|
|
|
|
|
m_caps[CapType::CustomDsData] = [this](Msg msg, Capability& data) -> Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
case Msg::GetDefault:
|
2020-08-31 07:44:24 +00:00
|
|
|
|
data = Capability::createOneValue<Bool>(CapType::CustomDsData,Bool(true));
|
2020-07-26 09:07:40 +00:00
|
|
|
|
return success();
|
2020-06-20 03:01:35 +00:00
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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(enmGet<Bool>, _1, _2, Bool(true));
|
|
|
|
|
|
|
|
|
|
m_query[CapType::FeederEnabled] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[CapType::FeederEnabled] = [this](Msg msg, Capability& data) -> Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
2020-08-31 07:44:24 +00:00
|
|
|
|
data = Capability::createOneValue<CapType::FeederEnabled>(Bool(m_bFeederEnabled));
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetCurrent:
|
2020-08-31 07:44:24 +00:00
|
|
|
|
data = Capability::createOneValue<CapType::FeederEnabled>(Bool(m_bFeederEnabled));
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::GetDefault:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
case Msg::Reset:
|
|
|
|
|
m_bFeederEnabled = true;
|
2020-08-31 07:44:24 +00:00
|
|
|
|
data = Capability::createOneValue<CapType::FeederEnabled>(Bool(true));
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<CapType::FeederEnabled>();
|
|
|
|
|
m_bFeederEnabled = mech;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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 {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
2020-08-31 07:44:24 +00:00
|
|
|
|
data = Capability::createOneValue<CapType::DuplexEnabled>(Bool(m_scanparam->is_duplex));
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<CapType::DuplexEnabled>(m_scanparam->is_duplex);
|
|
|
|
|
return success();
|
2020-07-11 10:43:17 +00:00
|
|
|
|
case Msg::Reset:
|
2020-06-20 03:01:35 +00:00
|
|
|
|
case Msg::GetDefault:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
m_scanparam->is_duplex = true;
|
|
|
|
|
data = Capability::createOneValue<CapType::DuplexEnabled>(true);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<CapType::DuplexEnabled>();
|
|
|
|
|
m_scanparam->is_duplex = mech;
|
2020-08-31 07:44:24 +00:00
|
|
|
|
//FileTools::write_log("D:\\1.txt", std::to_string(mech ? 1 : 0));
|
2020-08-15 08:42:43 +00:00
|
|
|
|
m_scanparam->is_autodiscradblank_normal = m_scanparam->is_autodiscradblank_vince = m_scanparam->en_fold = 0;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
if (!mech)
|
|
|
|
|
m_scanparam->is_backrotate180 = 0;//<2F><><EFBFBD>汳<EFBFBD><E6B1B3><EFBFBD><EFBFBD>ת180<38>㲻<EFBFBD><E3B2BB><EFBFBD><EFBFBD>
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
m_query[CapType::AutoFeed] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[CapType::AutoFeed] = [this](Msg msg, Capability& data) -> Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
2020-08-31 07:44:24 +00:00
|
|
|
|
data = Capability::createOneValue<CapType::AutoFeed>(m_bAutoFeed);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
|
|
|
|
// fallthrough
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<CapType::AutoFeed>(m_bAutoFeed);
|
|
|
|
|
return success();
|
2020-07-11 10:43:17 +00:00
|
|
|
|
case Msg::Reset:
|
2020-06-20 03:01:35 +00:00
|
|
|
|
case Msg::GetDefault:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
m_bAutoFeed = true;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data = Capability::createOneValue<CapType::AutoFeed>(true);
|
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<CapType::AutoFeed>();
|
|
|
|
|
m_bAutoFeed = mech;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2020-07-11 10:43:17 +00:00
|
|
|
|
//m_query[CapType::AutoScan] = msgSupportGetAllSetReset;
|
|
|
|
|
//m_caps[CapType::AutoScan] = [this](Msg msg, Capability& data) -> Result {
|
|
|
|
|
// switch (msg) {
|
|
|
|
|
// case Msg::Get:
|
|
|
|
|
// data = Capability::createEnumeration<CapType::AutoScan>(
|
|
|
|
|
// { Bool(), Bool(true) }, Bool(m_bAutoFeed));
|
|
|
|
|
// return success();
|
|
|
|
|
// // fallthrough
|
|
|
|
|
// case Msg::GetCurrent:
|
|
|
|
|
// data = Capability::createOneValue<CapType::AutoScan>(m_bAutoFeed);
|
|
|
|
|
// return success();
|
|
|
|
|
// case Msg::Reset:
|
|
|
|
|
// case Msg::GetDefault:
|
|
|
|
|
// m_bAutoFeed = true;
|
|
|
|
|
// data = Capability::createOneValue<CapType::AutoScan>(true);
|
|
|
|
|
// return success();
|
|
|
|
|
|
|
|
|
|
// case Msg::Set: {
|
|
|
|
|
// auto mech = data.currentItem<CapType::AutoScan>();
|
|
|
|
|
// m_bAutoFeed = mech;
|
|
|
|
|
// return success();
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// default:
|
|
|
|
|
// return capBadOperation();
|
|
|
|
|
// }
|
|
|
|
|
//};
|
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
m_query[CapType::IImageFileFormat] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[CapType::IImageFileFormat] = [this](Msg msg, Capability& data) -> Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get: {
|
|
|
|
|
UInt32 capindex = 0;
|
|
|
|
|
if (m_capImageFileFormat == ImageFileFormat::Tiff) capindex = 1;
|
|
|
|
|
if (m_capImageFileFormat == ImageFileFormat::Jfif) capindex = 2;
|
|
|
|
|
data = Capability::createEnumeration<CapType::IImageFileFormat>(
|
|
|
|
|
{ ImageFileFormat::Bmp, ImageFileFormat::Tiff,ImageFileFormat::Jfif }, capindex, 0);
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
case Msg::Reset:
|
2020-08-31 07:44:24 +00:00
|
|
|
|
case Msg::GetDefault:
|
2020-06-20 03:01:35 +00:00
|
|
|
|
m_capImageFileFormat = ImageFileFormat::Bmp;
|
|
|
|
|
data = Capability::createOneValue<CapType::IImageFileFormat>(m_capImageFileFormat);
|
|
|
|
|
return success();
|
2020-08-31 07:44:24 +00:00
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<CapType::IImageFileFormat>(m_capImageFileFormat);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<CapType::IImageFileFormat>();
|
|
|
|
|
if (mech == ImageFileFormat::Bmp ||
|
|
|
|
|
mech == ImageFileFormat::Tiff ||
|
|
|
|
|
mech == ImageFileFormat::Jfif) {
|
|
|
|
|
m_capImageFileFormat = mech;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return badValue();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//custom define
|
|
|
|
|
m_query[CapType::IAutomaticDeskew] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[CapType::IAutomaticDeskew] = [this](Msg msg, Capability& data)->Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
2020-11-12 11:42:16 +00:00
|
|
|
|
//data = Capability::createEnumeration<CapType::IAutomaticDeskew>(
|
|
|
|
|
// { Bool(), Bool(true) }, Bool(m_scanparam->autodescrew == 0 ? false : true));
|
|
|
|
|
data = Capability::createOneValue<CapType::IAutomaticDeskew>(m_scanparam->autodescrew);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
|
|
|
|
case Msg::Reset:
|
|
|
|
|
m_scanparam->autodescrew = true;
|
|
|
|
|
data = Capability::createOneValue<CapType::IAutomaticDeskew>(m_scanparam->autodescrew);
|
|
|
|
|
return success();
|
2020-08-31 07:44:24 +00:00
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<CapType::IAutomaticDeskew>(m_scanparam->autodescrew);
|
|
|
|
|
return success();
|
2020-06-20 03:01:35 +00:00
|
|
|
|
case Msg::GetDefault:
|
|
|
|
|
data = Capability::createOneValue<CapType::IAutomaticDeskew>(true);
|
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto atuodsw = data.currentItem<CapType::IAutomaticDeskew>();
|
|
|
|
|
m_scanparam->autodescrew = (bool)atuodsw;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
m_query[(CapType)(CapTypeEx::TwEx_SwitchFrontBack)] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[(CapType)(CapTypeEx::TwEx_SwitchFrontBack)] = [this](Msg msg, Capability& data)->Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
data = Capability::createEnumeration<Bool>((CapType)((CapType)(CapTypeEx::TwEx_SwitchFrontBack)), { Bool(),Bool(true) }, Bool(m_scanparam->is_switchfrontback), 0);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::Reset:
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
m_scanparam->is_switchfrontback = false;
|
|
|
|
|
data = Capability::createOneValue<Bool>((CapType)((CapType)(CapTypeEx::TwEx_SwitchFrontBack)), m_scanparam->is_switchfrontback);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetDefault:
|
|
|
|
|
data = Capability::createOneValue<Bool>((CapType)((CapType)(CapTypeEx::TwEx_SwitchFrontBack)), Bool(false));
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<Bool>();
|
|
|
|
|
m_scanparam->is_switchfrontback = mech;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
m_query[CapType::IAutomaticRotate] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[CapType::IAutomaticRotate] = [this](Msg msg, Capability& data)->Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<CapType::IAutomaticRotate>(m_scanparam->is_autotext);
|
|
|
|
|
return success();
|
2020-07-11 10:43:17 +00:00
|
|
|
|
case Msg::Reset:
|
2020-06-20 03:01:35 +00:00
|
|
|
|
case Msg::GetDefault:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
m_scanparam->is_autotext = false;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data = Capability::createOneValue<CapType::IAutomaticRotate>(false);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<CapType::IAutomaticRotate>();
|
|
|
|
|
m_scanparam->is_autotext = (bool)mech;
|
|
|
|
|
if (mech)
|
|
|
|
|
m_scanparam->imageRotateDegree = 0.0f;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2020-07-07 01:54:19 +00:00
|
|
|
|
m_query[CapType::IAutomaticCropUsesFrame] = msgSupportGetAll;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
m_caps[CapType::IAutomaticCropUsesFrame] = [this](Msg msg, Capability& data)->Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
2020-07-07 01:54:19 +00:00
|
|
|
|
data = Capability::Capability::createOneValue<CapType::IAutomaticCropUsesFrame>(m_scanparam->is_autocrop);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
|
|
|
|
case Msg::Reset:
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
m_scanparam->is_autocrop = false;
|
|
|
|
|
data = Capability::createOneValue<CapType::IAutomaticCropUsesFrame>(m_scanparam->is_autocrop);
|
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::GetDefault:
|
|
|
|
|
data = Capability::createOneValue<CapType::IAutomaticCropUsesFrame>(false);
|
|
|
|
|
return success();
|
|
|
|
|
|
2020-07-07 01:54:19 +00:00
|
|
|
|
//case Msg::Set: {
|
|
|
|
|
// auto autocrop = data.currentItem<CapType::IAutomaticCropUsesFrame>();
|
|
|
|
|
// m_scanparam->is_autocrop = (bool)autocrop;
|
|
|
|
|
// if (autocrop)
|
|
|
|
|
// m_scanparam->papertype = (byte)PaperSize::None;
|
|
|
|
|
// return success();
|
|
|
|
|
//}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
m_query[CapType::AutoScan] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[CapType::AutoScan] = [this](Msg msg, Capability& data)->Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
data = Capability::createEnumeration<CapType::AutoScan>(
|
|
|
|
|
{ Bool(), Bool(true) }, m_autoscan);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::Reset:
|
|
|
|
|
m_autoscan = true;
|
|
|
|
|
data = Capability::createOneValue<CapType::AutoScan>(m_autoscan);
|
|
|
|
|
return success();
|
2020-08-31 07:44:24 +00:00
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<CapType::AutoScan>(m_autoscan);
|
|
|
|
|
return success();
|
2020-07-07 01:54:19 +00:00
|
|
|
|
case Msg::GetDefault:
|
|
|
|
|
data = Capability::createOneValue<CapType::AutoScan>(true);
|
|
|
|
|
return success();
|
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
case Msg::Set: {
|
2020-07-07 01:54:19 +00:00
|
|
|
|
auto autoscan = data.currentItem<CapType::AutoScan>();
|
|
|
|
|
m_autoscan = autoscan;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
m_query[CapType::IAutoSize] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[CapType::IAutoSize] = [this](Msg msg, Capability& data)->Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
data = Capability::createEnumeration<CapType::IAutoSize>(
|
2020-07-11 10:43:17 +00:00
|
|
|
|
{ AutoSize::None, AutoSize::Auto}, (UInt16)m_autosize, 0);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
|
|
|
|
// fallthrough
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<CapType::IAutoSize>((AutoSize)m_autosize);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::Reset:
|
|
|
|
|
case Msg::GetDefault:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
m_autosize = (UInt16)AutoSize::None;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data = Capability::createOneValue<CapType::IAutoSize>(AutoSize::None);
|
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto autosize = data.currentItem<CapType::IAutoSize>();
|
2020-07-07 01:54:19 +00:00
|
|
|
|
if (autosize == AutoSize::Auto)
|
|
|
|
|
{
|
2020-11-12 11:42:16 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
2020-07-11 10:43:17 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_autoboarderdetcet = false;
|
|
|
|
|
m_scanparam->is_autocrop = 0;
|
2020-07-07 01:54:19 +00:00
|
|
|
|
}
|
2020-06-20 03:01:35 +00:00
|
|
|
|
m_autosize = (byte)autosize;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2020-07-07 01:54:19 +00:00
|
|
|
|
m_query[CapType::IAutomaticBorderDetection] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[CapType::IAutomaticBorderDetection] = [this](Msg msg, Capability& data)->Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
2020-08-31 07:44:24 +00:00
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<CapType::IAutomaticBorderDetection>(m_autoboarderdetcet);
|
2020-07-07 01:54:19 +00:00
|
|
|
|
return success();
|
|
|
|
|
case Msg::Reset:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
m_autoboarderdetcet = false;
|
2020-07-07 01:54:19 +00:00
|
|
|
|
data = Capability::createOneValue<CapType::IAutomaticBorderDetection>(m_autoboarderdetcet);
|
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::GetDefault:
|
|
|
|
|
data = Capability::createOneValue<CapType::IAutomaticBorderDetection>(false);
|
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto autodetectborder = data.currentItem<CapType::IAutomaticBorderDetection>();
|
|
|
|
|
if (autodetectborder)
|
|
|
|
|
{
|
2020-11-12 11:42:16 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
2020-07-11 10:43:17 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_autosize = (UInt16)AutoSize::None;
|
2020-07-07 01:54:19 +00:00
|
|
|
|
}
|
|
|
|
|
m_autoboarderdetcet = autodetectborder;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
m_query[CapType::IImageMerge] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[CapType::IImageMerge] = [this](Msg msg, Capability& data)->Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
data = Capability::createOneValue<UInt16>(CapType::IImageMerge, (UInt16)m_scanparam->en_fold);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::Reset:
|
|
|
|
|
m_scanparam->en_fold = 0;//Ĭ<>ϲ<EFBFBD><CFB2><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
data = Capability::createOneValue<UInt16>(CapType::IImageMerge, (UInt16)m_scanparam->en_fold);
|
|
|
|
|
return success();
|
2020-08-31 07:44:24 +00:00
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<UInt16>(CapType::IImageMerge, (UInt16)m_scanparam->en_fold);
|
|
|
|
|
return success();
|
2020-06-20 03:01:35 +00:00
|
|
|
|
|
|
|
|
|
case Msg::GetDefault:
|
|
|
|
|
data = Capability::createOneValue<UInt16>(CapType::IImageMerge, 0);
|
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
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>ƫ
|
2020-08-15 08:42:43 +00:00
|
|
|
|
m_scanparam->is_autodiscradblank_normal = m_scanparam->is_autodiscradblank_vince = 0;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
}
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
m_query[CapType::IAutoDiscardBlankPages] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[CapType::IAutoDiscardBlankPages] = [this](Msg msg, Capability& data)->Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
2020-08-31 07:44:24 +00:00
|
|
|
|
data = Capability::createOneValue<CapType::IAutoDiscardBlankPages>(m_scanparam->is_autodiscradblank_normal ? DiscardBlankPages::Auto : DiscardBlankPages::Disabled);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
|
|
|
|
case Msg::Reset:
|
|
|
|
|
case Msg::GetDefault:
|
|
|
|
|
m_scanparam->is_autodiscradblank_normal = false;
|
|
|
|
|
data = Capability::createOneValue<CapType::IAutoDiscardBlankPages>(DiscardBlankPages::Disabled);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<CapType::IAutoDiscardBlankPages>(m_scanparam->is_autodiscradblank_normal ? DiscardBlankPages::Auto : DiscardBlankPages::Disabled);
|
|
|
|
|
return success();
|
|
|
|
|
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<CapType::IAutoDiscardBlankPages>();
|
2020-08-31 07:44:24 +00:00
|
|
|
|
if ((mech != DiscardBlankPages::Auto) || (mech != DiscardBlankPages::Disabled))
|
|
|
|
|
return badValue();
|
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
m_scanparam->is_autodiscradblank_normal = (Int32)mech == (Int32)DiscardBlankPages::Auto;
|
2020-08-15 08:42:43 +00:00
|
|
|
|
m_scanparam->is_duplex = 1;
|
|
|
|
|
m_scanparam->en_fold = 0;
|
|
|
|
|
m_scanparam->is_autodiscradblank_vince = 0;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*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 {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
data = Capability::createEnumeration<Bool>((CapType)((CapType)(CapTypeEx::TwEx_IAutoDiscardBlankVince)), { Bool(),Bool(true) }, Bool(m_scanparam->is_autodiscradblank_vince), 0);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::Reset:
|
|
|
|
|
case Msg::GetDefault:
|
|
|
|
|
m_scanparam->is_autodiscradblank_vince = false;
|
|
|
|
|
data = Capability::createOneValue<Bool>((CapType)((CapType)(CapTypeEx::TwEx_IAutoDiscardBlankVince)), Bool(false));
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<Bool>((CapType)((CapType)(CapTypeEx::TwEx_IAutoDiscardBlankVince)), m_scanparam->is_autodiscradblank_vince);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<Bool>();
|
|
|
|
|
m_scanparam->is_autodiscradblank_vince = mech;
|
2020-08-15 08:42:43 +00:00
|
|
|
|
m_scanparam->is_duplex = 1;
|
|
|
|
|
m_scanparam->en_fold = 0;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
if (mech)
|
|
|
|
|
m_scanparam->is_autodiscradblank_normal = 0;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
m_query[(CapType)(CapTypeEx::TwEx_IBackRotate180)] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[(CapType)(CapTypeEx::TwEx_IBackRotate180)] = [this](Msg msg, Capability& data)->Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
data = Capability::createEnumeration<Bool>((CapType)(CapTypeEx::TwEx_IBackRotate180), { Bool(),Bool(true) }, Bool(m_scanparam->is_backrotate180), 0);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::Reset:
|
|
|
|
|
case Msg::GetDefault:
|
|
|
|
|
m_scanparam->is_backrotate180 = false;
|
|
|
|
|
data = Capability::createOneValue<Bool>((CapType)(CapTypeEx::TwEx_IBackRotate180), Bool(false));
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<Bool>((CapType)(CapTypeEx::TwEx_IBackRotate180), m_scanparam->is_backrotate180);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<Bool>();
|
|
|
|
|
m_scanparam->is_backrotate180 = mech;
|
|
|
|
|
if (mech)
|
|
|
|
|
m_scanparam->is_duplex = 1;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD>ڿ<EFBFBD>
|
|
|
|
|
m_query[(CapType)(CapTypeEx::TwEx_IFillBackground)] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[(CapType)(CapTypeEx::TwEx_IFillBackground)] = [this](Msg msg, Capability& data)->Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
data = Capability::createEnumeration<Bool>((CapType)(CapTypeEx::TwEx_IFillBackground), { Bool(),Bool(true) }, Bool(m_scanparam->fillbackground), 0);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<Bool>((CapType)(CapTypeEx::TwEx_IFillBackground), m_scanparam->fillbackground);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::Reset:
|
|
|
|
|
case Msg::GetDefault:
|
2020-11-16 10:05:04 +00:00
|
|
|
|
m_scanparam->fillbackground = true;
|
|
|
|
|
data = Capability::createOneValue<Bool>((CapType)(CapTypeEx::TwEx_IFillBackground), Bool(true));
|
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<Bool>();
|
|
|
|
|
m_scanparam->fillbackground = mech;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//<2F><EFBFBD><EEB4A9>
|
|
|
|
|
m_query[(CapType)(CapTypeEx::TwEx_IFillHole)] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[(CapType)(CapTypeEx::TwEx_IFillHole)] = [this](Msg msg, Capability& data)->Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
data = Capability::createEnumeration<Bool>((CapType)(CapTypeEx::TwEx_IFillHole), { Bool(),Bool(true) }, Bool(m_scanparam->fillhole.is_fillhole), 0);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<Bool>((CapType)(CapTypeEx::TwEx_IFillHole), m_scanparam->fillhole.is_fillhole);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetDefault:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
case Msg::Reset:
|
|
|
|
|
m_scanparam->fillhole.is_fillhole = false;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data = Capability::createOneValue<Bool>((CapType)(CapTypeEx::TwEx_IFillHole), Bool(false));
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<Bool>();
|
|
|
|
|
m_scanparam->fillhole.is_fillhole = mech;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
m_query[(CapType)(CapTypeEx::TwEx_IFillHoleRatio)] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[(CapType)(CapTypeEx::TwEx_IFillHoleRatio)] = [this](Msg msg, Capability& data)->Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
data = Capability::createOneValue<Int32>((CapType)(CapTypeEx::TwEx_IFillHoleRatio), m_scanparam->fillhole.fillholeratio);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<Int32>((CapType)(CapTypeEx::TwEx_IFillHoleRatio), m_scanparam->fillhole.fillholeratio);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetDefault:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
case Msg::Reset:
|
|
|
|
|
m_scanparam->fillhole.fillholeratio = 10;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data = Capability::createOneValue<Int32>((CapType)(CapTypeEx::TwEx_IFillHoleRatio), Int32(10));
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<Int32>();
|
|
|
|
|
if (mech > 0 && mech < 50) {
|
|
|
|
|
m_scanparam->fillhole.fillholeratio = (int)mech;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
return badValue();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//<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 {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
data = Capability::createEnumeration<Bool>((CapType)(CapTypeEx::TwEx_IMultiOutputRed), { Bool(),Bool(true) }, Bool(m_scanparam->multi_output_red), 0);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<Bool>((CapType)(CapTypeEx::TwEx_IMultiOutputRed), m_scanparam->multi_output_red);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetDefault:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
case Msg::Reset:
|
|
|
|
|
m_scanparam->multi_output_red = false;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data = Capability::createOneValue<Bool>((CapType)(CapTypeEx::TwEx_IMultiOutputRed), Bool(false));
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<Bool>();
|
|
|
|
|
if (m_scanparam->pixtype == (byte)PixelType::Rgb)
|
|
|
|
|
m_scanparam->multi_output_red = mech;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_scanparam->multi_output_red = 0;//<2F>Dz<EFBFBD>ɫ <20><><EFBFBD><EFBFBD>ʹ<EFBFBD>ö<EFBFBD><C3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
}
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2020-06-23 09:31:43 +00:00
|
|
|
|
//<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 {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
data = Capability::createEnumeration<Bool>((CapType)(CapTypeEx::TwEx_HsvCorrect), { Bool(),Bool(true) }, Bool(m_scanparam->hsvcorrect), 0);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<Bool>((CapType)(CapTypeEx::TwEx_HsvCorrect), m_scanparam->hsvcorrect);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::Reset:
|
|
|
|
|
case Msg::GetDefault:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
m_scanparam->hsvcorrect = false;
|
2020-06-23 09:31:43 +00:00
|
|
|
|
data = Capability::createOneValue<Bool>((CapType)(CapTypeEx::TwEx_HsvCorrect), Bool(false));
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<Bool>();
|
|
|
|
|
m_scanparam->hsvcorrect = mech;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
m_query[CapType::IFilter] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[CapType::IFilter] = [this](Msg msg, Capability& data)->Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
data = Capability::createEnumeration<CapType::IFilter>({ Filter::Red,Filter::Green,Filter::Blue,Filter::None },
|
|
|
|
|
m_scanparam->filter,
|
|
|
|
|
0);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<CapType::IFilter>((Filter)m_scanparam->filter);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetDefault:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
case Msg::Reset:
|
|
|
|
|
m_scanparam->filter = (byte)Filter::None;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data = Capability::createOneValue<CapType::IFilter>(Filter::None);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<CapType::IFilter>();
|
|
|
|
|
if (mech == Filter::None || mech == Filter::Red || mech == Filter::Green || mech == Filter::Blue) {
|
|
|
|
|
m_scanparam->filter = (byte)mech;
|
|
|
|
|
if (mech != Filter::None)
|
|
|
|
|
{
|
|
|
|
|
m_scanparam->enhance_color = (byte)Enchace_Color::Enhance_None;
|
|
|
|
|
}
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
return badValue();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//<2F><>ɫ<EFBFBD><C9AB>ǿ
|
|
|
|
|
m_query[(CapType)(CapTypeEx::TwEx_IEnhanceColor)] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[(CapType)(CapTypeEx::TwEx_IEnhanceColor)] = [this](Msg msg, Capability& data)->Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
data = Capability::createEnumeration<Enchace_Color>((CapType)(CapTypeEx::TwEx_IEnhanceColor),
|
|
|
|
|
{ Enchace_Color::Enhance_None,Enchace_Color::Enhance_Red,Enchace_Color::Enhance_Green,Enchace_Color::Enhance_Blue },
|
|
|
|
|
m_scanparam->enhance_color,
|
|
|
|
|
0);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<Int16>((CapType)(CapTypeEx::TwEx_IEnhanceColor), (Enchace_Color)(m_scanparam->enhance_color));
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetDefault:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
case Msg::Reset:
|
|
|
|
|
m_scanparam->enhance_color = Enchace_Color::Enhance_None;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data = Capability::createOneValue<Int16>((CapType)(CapTypeEx::TwEx_IEnhanceColor), Enchace_Color::Enhance_None);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<Int16>();
|
|
|
|
|
if (m_scanparam->pixtype == (byte)PixelType::Rgb)
|
|
|
|
|
{
|
|
|
|
|
m_scanparam->enhance_color = (byte)Enchace_Color::Enhance_None;
|
|
|
|
|
}
|
|
|
|
|
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 badValue();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
m_query[(CapType)(CapTypeEx::TwEx_Sharpen)] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[(CapType)(CapTypeEx::TwEx_Sharpen)] = [this](Msg msg, Capability& data)->Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
data = Capability::createEnumeration<SharpenBlur>((CapType)(CapTypeEx::TwEx_Sharpen), { SharpenBlur::Sharpen_None,SharpenBlur::Sharpen_Normal,SharpenBlur::Sharpen_More,SharpenBlur::Sharpen_Blur,SharpenBlur::Sharpen_Blur_More },
|
|
|
|
|
m_scanparam->sharpen,
|
|
|
|
|
0);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<Int16>((CapType)(CapTypeEx::TwEx_Sharpen), (SharpenBlur)(m_scanparam->sharpen));
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetDefault:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
case Msg::Reset:
|
|
|
|
|
m_scanparam->sharpen = SharpenBlur::Sharpen_None;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data = Capability::createOneValue<Int16>((CapType)(CapTypeEx::TwEx_Sharpen), SharpenBlur::Sharpen_None);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<Int16>();
|
|
|
|
|
if (m_scanparam->pixtype == (int)PixelType::BlackWhite)
|
|
|
|
|
return badValue();
|
|
|
|
|
m_scanparam->sharpen = (byte)mech;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*<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 {
|
|
|
|
|
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:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
case Msg::Reset:
|
|
|
|
|
m_scanparam->brightness = 0.0f;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
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 {
|
|
|
|
|
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:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
case Msg::Reset:
|
|
|
|
|
m_scanparam->contrast = 0.0f;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
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 {
|
|
|
|
|
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:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
case Msg::Reset:
|
|
|
|
|
m_scanparam->gamma = 1.0f;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//m_query[(CapType)(CapTypeEx::TwEx_DBAreaNum)] = msgSupportGetAllSetReset;
|
|
|
|
|
//m_caps[(CapType)(CapTypeEx::TwEx_DBAreaNum)] = [this](Msg msg, Capability& data)->Result {
|
|
|
|
|
// switch (msg) {
|
|
|
|
|
// case Msg::Get:
|
|
|
|
|
// data = Capability::createOneValue<UInt16>((CapType)(CapTypeEx::TwEx_DBAreaNum), m_scanparam->areanum);
|
|
|
|
|
// return success();
|
|
|
|
|
// case Msg::Reset:
|
|
|
|
|
// m_scanparam->areanum = 8;
|
|
|
|
|
// case Msg::GetCurrent:
|
|
|
|
|
// data = Capability::createOneValue<UInt16>((CapType)(CapTypeEx::TwEx_DBAreaNum), m_scanparam->areanum);
|
|
|
|
|
// return success();
|
|
|
|
|
// case Msg::GetDefault:
|
|
|
|
|
// data = Capability::createOneValue<UInt16>((CapType)(CapTypeEx::TwEx_DBAreaNum), UInt16(8));
|
|
|
|
|
// return success();
|
|
|
|
|
// case Msg::Set: {
|
|
|
|
|
// auto mech = data.currentItem<UInt16>();
|
|
|
|
|
// if (mech >= 5 && mech <= 40) {
|
|
|
|
|
// m_scanparam->areanum = mech;
|
|
|
|
|
// return success();
|
|
|
|
|
// }
|
|
|
|
|
// return badValue();
|
|
|
|
|
// }
|
|
|
|
|
// default:
|
|
|
|
|
// return capBadOperation();
|
|
|
|
|
// }
|
|
|
|
|
//};
|
|
|
|
|
|
|
|
|
|
//m_query[(CapType)(CapTypeEx::TwEx_DBDevnMax)] = msgSupportGetAllSetReset;
|
|
|
|
|
//m_caps[(CapType)(CapTypeEx::TwEx_DBDevnMax)] = [this](Msg msg, Capability& data)->Result {
|
|
|
|
|
// switch (msg) {
|
|
|
|
|
// case Msg::Get:
|
|
|
|
|
// data = Capability::createOneValue<UInt16>((CapType)(CapTypeEx::TwEx_DBDevnMax), m_scanparam->devnmax);
|
|
|
|
|
// return success();
|
|
|
|
|
// case Msg::Reset:
|
|
|
|
|
// m_scanparam->devnmax = 200;
|
|
|
|
|
// case Msg::GetCurrent:
|
|
|
|
|
// data = Capability::createOneValue<UInt16>((CapType)(CapTypeEx::TwEx_DBDevnMax), m_scanparam->devnmax);
|
|
|
|
|
// return success();
|
|
|
|
|
// case Msg::GetDefault:
|
|
|
|
|
// data = Capability::createOneValue<UInt16>((CapType)(CapTypeEx::TwEx_DBDevnMax), UInt16(200));
|
|
|
|
|
// return success();
|
|
|
|
|
// case Msg::Set: {
|
|
|
|
|
// auto mech = data.currentItem<UInt16>();
|
|
|
|
|
// if (mech >= 150 && mech <= 400) {
|
|
|
|
|
// m_scanparam->devnmax = mech;
|
|
|
|
|
// return success();
|
|
|
|
|
// }
|
|
|
|
|
// return badValue();
|
|
|
|
|
// }
|
|
|
|
|
// 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 {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
data = Capability::createEnumeration<Bool>((CapType)(CapTypeEx::TwEx_ScrewDetectEnable), { Bool(),Bool(true) }, Bool(m_scanparam->hardwarecaps.en_skrewdetect), 0);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<Bool>((CapType)(CapTypeEx::TwEx_ScrewDetectEnable), m_scanparam->hardwarecaps.en_skrewdetect);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetDefault:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
case Msg::Reset:
|
|
|
|
|
m_scanparam->hardwarecaps.en_skrewdetect = false;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data = Capability::createOneValue<Bool>((CapType)(CapTypeEx::TwEx_ScrewDetectEnable), Bool(false));
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<Bool>();
|
|
|
|
|
m_scanparam->hardwarecaps.en_skrewdetect = mech;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
m_query[(CapType)(CapTypeEx::TwEx_ScrewLevel)] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[(CapType)(CapTypeEx::TwEx_ScrewLevel)] = [this](Msg msg, Capability& data)->Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
data = Capability::createOneValue<UInt8>((CapType)(CapTypeEx::TwEx_ScrewLevel), m_scanparam->hardwarecaps.skrewdetectlevel);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<UInt8>((CapType)(CapTypeEx::TwEx_ScrewLevel), m_scanparam->hardwarecaps.skrewdetectlevel);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetDefault:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
case Msg::Reset:
|
|
|
|
|
m_scanparam->hardwarecaps.skrewdetectlevel = 3;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data = Capability::createOneValue<UInt8>((CapType)(CapTypeEx::TwEx_ScrewLevel), UInt8(3));
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<UInt8>();
|
|
|
|
|
if (mech >= 1 && mech <= 5) {
|
|
|
|
|
m_scanparam->hardwarecaps.skrewdetectlevel = mech;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
return badValue();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//װ<><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
m_query[(CapType)(CapTypeEx::TwEx_StableDetectEnable)] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[(CapType)(CapTypeEx::TwEx_StableDetectEnable)] = [this](Msg msg, Capability& data)->Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
data = Capability::createEnumeration<Bool>((CapType)(CapTypeEx::TwEx_StableDetectEnable), { Bool(),Bool(true) }, Bool(m_scanparam->hardwarecaps.en_stapledetect), 0);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<Bool>((CapType)(CapTypeEx::TwEx_StableDetectEnable), m_scanparam->hardwarecaps.en_stapledetect);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetDefault:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
case Msg::Reset:
|
|
|
|
|
m_scanparam->hardwarecaps.en_stapledetect = false;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data = Capability::createOneValue<Bool>((CapType)(CapTypeEx::TwEx_StableDetectEnable), Bool(false));
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<Bool>();
|
|
|
|
|
m_scanparam->hardwarecaps.en_stapledetect = mech;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-16 10:05:04 +00:00
|
|
|
|
|
|
|
|
|
m_query[(CapType)(CapTypeEx::TwEx_DogEarDelection)] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[(CapType)(CapTypeEx::TwEx_DogEarDelection)] = [this](Msg msg, Capability& data)->Result {
|
|
|
|
|
switch (msg)
|
|
|
|
|
{
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<Bool>((CapType)CapTypeEx::TwEx_DogEarDelection, m_scanparam->is_dogeardetection);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetDefault:
|
|
|
|
|
case Msg::Reset:
|
|
|
|
|
m_scanparam->is_dogeardetection = false;
|
|
|
|
|
data = Capability::createOneValue<Bool>((CapType)(CapTypeEx::TwEx_DogEarDelection), Bool(false));
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::Set:
|
|
|
|
|
{
|
|
|
|
|
auto mech = data.currentItem<Bool>();
|
|
|
|
|
m_scanparam->is_dogeardetection= mech;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
2020-06-20 03:01:35 +00:00
|
|
|
|
//˫<>ż<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>
|
|
|
|
|
m_query[CapType::DoubleFeedDetection] = msgSupportGetAllSetReset;
|
|
|
|
|
m_caps[CapType::DoubleFeedDetection] = [this](Msg msg, Capability& data)->Result {
|
|
|
|
|
switch (msg) {
|
|
|
|
|
case Msg::Get:
|
|
|
|
|
case Msg::GetCurrent:
|
|
|
|
|
data = Capability::createOneValue<Bool>(CapType::DoubleFeedDetection, m_scanparam->hardwarecaps.en_doublefeed);
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::GetDefault:
|
2020-07-11 10:43:17 +00:00
|
|
|
|
case Msg::Reset:
|
|
|
|
|
m_scanparam->hardwarecaps.en_doublefeed = false;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data = Capability::createOneValue<Bool>(CapType::DoubleFeedDetection, Bool(false));
|
|
|
|
|
return success();
|
|
|
|
|
case Msg::Set: {
|
|
|
|
|
auto mech = data.currentItem<Bool>();
|
|
|
|
|
m_scanparam->hardwarecaps.en_doublefeed = mech;
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return capBadOperation();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
return success();
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::identityCloseDs(const Identity&) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
// no need to explicitly release any resources if using RAII
|
|
|
|
|
// TWPP will free the whole source on its own after this method
|
|
|
|
|
|
2020-08-31 07:44:24 +00:00
|
|
|
|
if (guiIndicator)
|
|
|
|
|
guiIndicator->DestroyWindow();
|
2020-07-26 09:07:40 +00:00
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
if (guiTwain.get())
|
|
|
|
|
guiTwain.reset();
|
|
|
|
|
|
|
|
|
|
if (guiBridge.get())
|
|
|
|
|
guiBridge.reset();
|
2020-06-23 09:31:43 +00:00
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
scanner.reset();
|
2020-11-16 10:05:04 +00:00
|
|
|
|
bmpData.reset();
|
2020-06-20 03:01:35 +00:00
|
|
|
|
if (hMutex)
|
|
|
|
|
{
|
|
|
|
|
ReleaseMutex(hMutex);
|
|
|
|
|
CloseHandle(hMutex);
|
|
|
|
|
}
|
2020-07-11 10:43:17 +00:00
|
|
|
|
//saveGscanCapSetting();
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::pendingXfersGet(const Identity&, PendingXfers& data) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data.setCount(m_pendingXfers);
|
|
|
|
|
return success();
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::pendingXfersEnd(const Identity&, PendingXfers& data) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
//!< end xfer if set count 0
|
2020-11-16 10:05:04 +00:00
|
|
|
|
if (bmpData->size() > 0)
|
|
|
|
|
{
|
|
|
|
|
bmpData.reset(new std::vector<unsigned char>);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ret = scanner->aquire_bmpdata(*bmpData.get());
|
2020-07-26 09:07:40 +00:00
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
if (ret != 0) {
|
|
|
|
|
scanner->Set_ErrorCode(0);
|
2020-08-31 07:44:24 +00:00
|
|
|
|
if (guiIndicator)
|
2020-08-15 08:42:43 +00:00
|
|
|
|
guiIndicator->ShowWindow(SW_HIDE);
|
2020-08-31 07:44:24 +00:00
|
|
|
|
//if (guiIndicator.get())
|
|
|
|
|
// guiIndicator.reset();
|
|
|
|
|
//guiIndicator->ShowWindow(SW_HIDE);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
if (ret != -1) {
|
2020-07-07 01:54:19 +00:00
|
|
|
|
CString str;
|
|
|
|
|
str.Format(_T("%d"), ret);
|
|
|
|
|
ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), str, NULL, SW_HIDE);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
#ifndef G200
|
|
|
|
|
scanner->clear_hwerror();
|
|
|
|
|
#endif // G200
|
|
|
|
|
}
|
|
|
|
|
m_pendingXfers = 0;
|
|
|
|
|
if (guiTwain.get()) {
|
|
|
|
|
((CTwainUI*)(guiTwain.get()))->EnableID_OKorID_Cancel(true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
m_pendingXfers = 1;
|
|
|
|
|
}
|
|
|
|
|
data.setCount(m_pendingXfers);
|
|
|
|
|
return success();
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::pendingXfersReset(const Identity&, PendingXfers& data) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data.setCount(0);
|
2020-07-20 02:29:10 +00:00
|
|
|
|
if (scanner.get())
|
|
|
|
|
{
|
|
|
|
|
scanner->Stop_scan();
|
|
|
|
|
scanner->reset();
|
|
|
|
|
scanner->ResetScanner();
|
|
|
|
|
}
|
2020-08-31 07:44:24 +00:00
|
|
|
|
//guiIndicator.reset();
|
|
|
|
|
if (guiIndicator)
|
|
|
|
|
guiIndicator->DestroyWindow();
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::setupMemXferGet(const Identity&, SetupMemXfer& data) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
auto bpl = bytesPerLine();
|
|
|
|
|
auto max = bpl * static_cast<UInt32>(header()->biHeight);
|
2020-03-11 01:58:06 +00:00
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data.setMinSize(bpl);
|
|
|
|
|
data.setPreferredSize(max);
|
|
|
|
|
data.setMaxSize(max);
|
|
|
|
|
return success();
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::userInterfaceDisable(const Identity&, UserInterface& ui) {
|
2020-07-20 02:29:10 +00:00
|
|
|
|
//FileTools::write_log("D:\\1.txt", "userInterfaceDisable enter");
|
|
|
|
|
|
2020-07-26 09:07:40 +00:00
|
|
|
|
if(guiTwain.get())
|
|
|
|
|
guiTwain.reset();
|
2020-03-11 01:58:06 +00:00
|
|
|
|
|
|
|
|
|
#if TWPP_DETAIL_OS_WIN
|
2020-07-26 09:07:40 +00:00
|
|
|
|
if(guiBridge.get())
|
|
|
|
|
guiBridge.reset();
|
2020-03-11 01:58:06 +00:00
|
|
|
|
#endif
|
2020-07-20 02:29:10 +00:00
|
|
|
|
//FileTools::write_log("D:\\1.txt", "userInterfaceDisable exit");
|
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::userInterfaceEnable(const Identity&, UserInterface& ui) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
m_pendingXfers = 1;
|
|
|
|
|
m_memXferYOff = 0;
|
2020-07-11 10:43:17 +00:00
|
|
|
|
scanner->ResetMsgFiter();
|
2020-06-20 03:01:35 +00:00
|
|
|
|
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
|
|
|
|
|
setState(DsState::Enabled);
|
2020-09-21 01:25:46 +00:00
|
|
|
|
auto ret = startScan();
|
2020-11-16 10:05:04 +00:00
|
|
|
|
if (ret.status().condition() == Twpp::CC::NoMedia)
|
|
|
|
|
return ret;
|
|
|
|
|
//if (ret == success()) {
|
|
|
|
|
//m_pendingXfers = 1;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
auto notified = notifyXferReady();
|
|
|
|
|
return success();
|
2020-11-16 10:05:04 +00:00
|
|
|
|
//}
|
|
|
|
|
//else {
|
|
|
|
|
// m_pendingXfers = 0;
|
|
|
|
|
// setState(DsState::Open);
|
|
|
|
|
// return ret;
|
|
|
|
|
//}
|
2020-06-20 03:01:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return showTwainUI(ui);
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::userInterfaceEnableUiOnly(const Identity&, UserInterface& ui) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
// as a minimal source, we do not support GUI that just saves settings
|
|
|
|
|
return showTwainUI(ui, true);
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::imageInfoGet(const Identity&, ImageInfo& data) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
// our image does not change
|
|
|
|
|
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);
|
2020-08-31 07:44:24 +00:00
|
|
|
|
data.compression(m_compression);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
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();
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::imageLayoutGet(const Identity&, ImageLayout& data) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
// our image does not change
|
|
|
|
|
auto dib = header();
|
|
|
|
|
|
|
|
|
|
data.setDocumentNumber(1);
|
|
|
|
|
data.setFrameNumber(1);
|
|
|
|
|
data.setPageNumber(1);
|
2020-08-15 08:42:43 +00:00
|
|
|
|
data.setFrame(Frame(0, 0, static_cast<float>(dib->biWidth) / m_scanparam->resolution_dst, static_cast<float>(dib->biHeight) / m_scanparam->resolution_dst));
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::imageLayoutGetDefault(const Identity& origin, ImageLayout& data) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return imageLayoutGet(origin, data);
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::imageLayoutSet(const Identity& origin, ImageLayout& lay) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
// we dont support setting image frame
|
2020-03-11 01:58:06 +00:00
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
ImageLayout def;
|
|
|
|
|
imageLayoutGetDefault(origin, def);
|
2020-03-11 01:58:06 +00:00
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return lay.frame() == def.frame() ? success() : badValue();
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::imageLayoutReset(const Identity& origin, ImageLayout& data) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return imageLayoutGet(origin, data);
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::imageMemXferGet(const Identity& origin, ImageMemXfer& data) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
if (!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();
|
|
|
|
|
if (memSize > setup.maxSize() || memSize < setup.minSize()) {
|
|
|
|
|
return badValue();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto maxRows = memSize / bpl;
|
|
|
|
|
auto rows = std::min<UInt32>(maxRows, static_cast<UInt32>(dib->biHeight) - m_memXferYOff);
|
|
|
|
|
if (rows == 0) {
|
|
|
|
|
return seqError(); // image already transfered in this session
|
|
|
|
|
}
|
2020-08-31 07:44:24 +00:00
|
|
|
|
cv::Mat mat;
|
|
|
|
|
vector<uchar> cmpdata;
|
|
|
|
|
if (m_compression == Compression::Group4)
|
|
|
|
|
{
|
2020-11-16 10:05:04 +00:00
|
|
|
|
mat = cv::imdecode(*bmpData.get(), cv::IMREAD_GRAYSCALE);
|
2020-08-31 07:44:24 +00:00
|
|
|
|
G4Tiff gt(mat,G4Tiff::Mode::MemoryMode,"",120,m_scanparam->resolution_dst);
|
|
|
|
|
gt.GetCompressedData(cmpdata);
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data.setBytesPerRow(bpl);
|
|
|
|
|
data.setColumns(static_cast<UInt32>(dib->biWidth));
|
|
|
|
|
data.setRows(rows);
|
2020-08-31 07:44:24 +00:00
|
|
|
|
data.setBytesWritten(m_compression==Compression::None?bpl*rows: cmpdata.size());
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data.setXOffset(0);
|
|
|
|
|
data.setYOffset(m_memXferYOff);
|
2020-08-31 07:44:24 +00:00
|
|
|
|
data.setCompression(m_compression);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
|
|
|
|
|
auto lock = data.memory().data();
|
|
|
|
|
char* out = lock.data();
|
|
|
|
|
// bottom-up BMP -> top-down memory transfer
|
2020-08-31 07:44:24 +00:00
|
|
|
|
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);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
|
2020-08-31 07:44:24 +00:00
|
|
|
|
char* line = out;
|
|
|
|
|
out += bpl;
|
|
|
|
|
begin -= bpl;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
|
2020-08-31 07:44:24 +00:00
|
|
|
|
if (dib->biBitCount == 24)
|
|
|
|
|
{
|
|
|
|
|
//BGR BMP -> RGB memory transfer
|
|
|
|
|
for (; line + 3 < out; line += 3) {
|
|
|
|
|
std::swap(line[0], line[2]);
|
|
|
|
|
}
|
2020-06-20 03:01:35 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-08-31 07:44:24 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
std::copy(cmpdata.data(), cmpdata.data() + cmpdata.size(), out);
|
|
|
|
|
}
|
2020-06-20 03:01:35 +00:00
|
|
|
|
|
|
|
|
|
m_memXferYOff += rows;
|
|
|
|
|
|
|
|
|
|
if (m_memXferYOff >= static_cast<UInt32>(std::abs(dib->biHeight))) {
|
|
|
|
|
m_pendingXfers = 0;
|
|
|
|
|
m_memXferYOff = 0;
|
2020-11-16 10:05:04 +00:00
|
|
|
|
bmpData.reset(new std::vector<unsigned char>);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return { ReturnCode::XferDone, ConditionCode::Success };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return success();
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
2020-09-21 01:25:46 +00:00
|
|
|
|
//#define LOG_NORMAL
|
2020-03-11 01:58:06 +00:00
|
|
|
|
#ifdef LOG_NORMAL
|
|
|
|
|
static int xtfer = 0;
|
|
|
|
|
#endif
|
2020-09-21 01:25:46 +00:00
|
|
|
|
static int xtfer = 0;
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Result HuagaoDs::imageNativeXferGet(const Identity& id, ImageNativeXfer& data) {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
if (!m_pendingXfers) {
|
|
|
|
|
return seqError();
|
|
|
|
|
}
|
2020-11-16 10:05:04 +00:00
|
|
|
|
if (m_haveError)
|
|
|
|
|
return { ReturnCode::Cancel, ConditionCode::Success };
|
2020-06-20 03:01:35 +00:00
|
|
|
|
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());
|
2020-11-16 10:05:04 +00:00
|
|
|
|
bmpData.reset(new std::vector<unsigned char>);
|
2020-03-11 01:58:06 +00:00
|
|
|
|
#ifdef LOG_NORMAL
|
|
|
|
|
|
2020-09-21 01:25:46 +00:00
|
|
|
|
#endif // LOG
|
|
|
|
|
//std::string info = "Twain transfered num of " + to_string(++xtfer)+" images";
|
|
|
|
|
//FileTools::write_log("D:\\1.txt", info);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return { ReturnCode::XferDone, ConditionCode::Success };
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Twpp::Result HuagaoDs::pendingXfersStopFeeder(const Identity& origin, PendingXfers& data)
|
|
|
|
|
{
|
2020-07-20 02:29:10 +00:00
|
|
|
|
//FileTools::write_log("D:\\1.txt", "pendingXfersStopFeeder enter");
|
2020-06-20 03:01:35 +00:00
|
|
|
|
if (!scanner.get())
|
|
|
|
|
return seqError();
|
|
|
|
|
if (scanner->IsConnected()) {
|
|
|
|
|
scanner->Stop_scan();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data.setCount(scanner->Get_IsImageQueueEmpty() ? 0 : 1);
|
2020-07-20 02:29:10 +00:00
|
|
|
|
//FileTools::write_log("D:\\1.txt", "pendingXfersStopFeeder exit");
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
2020-05-16 01:59:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Twpp::Result HuagaoDs::setupFileXferGet(const Twpp::Identity& origin, Twpp::SetupFileXfer& data)
|
|
|
|
|
{
|
2020-06-20 03:01:35 +00:00
|
|
|
|
data.setFilePath(m_fileXfer.filePath());
|
|
|
|
|
data.setFormat(m_fileXfer.format());
|
|
|
|
|
return success();
|
2020-05-16 01:59:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Twpp::Result HuagaoDs::setupFileXferGetDefault(const Twpp::Identity& origin, Twpp::SetupFileXfer& data)
|
|
|
|
|
{
|
2020-06-20 03:01:35 +00:00
|
|
|
|
Str255 str("HGTwain.bmp");
|
|
|
|
|
data.setFilePath(str);
|
|
|
|
|
data.setFormat(ImageFileFormat::Bmp);
|
|
|
|
|
return success();
|
2020-05-16 01:59:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Twpp::Result HuagaoDs::setupFileXferSet(const Twpp::Identity& origin, Twpp::SetupFileXfer& data)
|
|
|
|
|
{
|
2020-06-20 03:01:35 +00:00
|
|
|
|
m_fileXfer.setFilePath(data.filePath());
|
|
|
|
|
m_fileXfer.setFormat(data.format());
|
|
|
|
|
return success();
|
2020-05-16 01:59:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Twpp::Result HuagaoDs::setupFileXferReset(const Twpp::Identity& origin, Twpp::SetupFileXfer& data)
|
|
|
|
|
{
|
2020-06-20 03:01:35 +00:00
|
|
|
|
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();
|
2020-05-16 01:59:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-07-26 09:07:40 +00:00
|
|
|
|
static int indeximg = 0;
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
Twpp::Result HuagaoDs::imageFileXferGet(const Twpp::Identity& origin)
|
|
|
|
|
{
|
2020-06-20 03:01:35 +00:00
|
|
|
|
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) {
|
2020-11-16 10:05:04 +00:00
|
|
|
|
if (bmpData->size() > 0) {
|
|
|
|
|
fwrite(bmpData->data(), 1, bmpData->size(), pfile);
|
|
|
|
|
bmpData.reset(new std::vector<unsigned char>);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
fclose(pfile);
|
2020-08-15 08:42:43 +00:00
|
|
|
|
return Result(ReturnCode::XferDone, ConditionCode::Success);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return Result(ReturnCode::Failure, ConditionCode::BadValue);
|
|
|
|
|
}
|
|
|
|
|
case ImageFileFormat::Tiff:
|
|
|
|
|
case ImageFileFormat::Jfif: {
|
2020-07-26 09:07:40 +00:00
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
BITMAPINFOHEADER& bmpinfo = *((BITMAPINFOHEADER*)header());
|
|
|
|
|
int decodetype;
|
|
|
|
|
if (bmpinfo.biBitCount == 24)
|
|
|
|
|
decodetype = cv::IMREAD_COLOR;
|
|
|
|
|
else
|
|
|
|
|
decodetype = cv::IMREAD_GRAYSCALE;
|
|
|
|
|
|
2020-07-26 09:07:40 +00:00
|
|
|
|
|
2020-11-16 10:05:04 +00:00
|
|
|
|
cv::Mat ims = cv::imdecode(*bmpData.get(), decodetype);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
|
2020-08-31 07:44:24 +00:00
|
|
|
|
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);
|
|
|
|
|
cv::imwrite(filename, ims, compression_params);
|
|
|
|
|
}
|
2020-11-16 10:05:04 +00:00
|
|
|
|
bmpData.reset(new std::vector<unsigned char>);
|
|
|
|
|
ims.release();
|
2020-08-15 08:42:43 +00:00
|
|
|
|
return Result(ReturnCode::XferDone, ConditionCode::Success);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return badProtocol();
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Twpp::Result HuagaoDs::showTwainUI(Twpp::UserInterface& ui, bool bUiOnly)
|
|
|
|
|
{
|
2020-06-20 03:01:35 +00:00
|
|
|
|
// 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);
|
|
|
|
|
|
|
|
|
|
//if (ui.modalUi()) {
|
|
|
|
|
// long appFlags = GetWindowLong(appWindow, GWL_STYLE);
|
|
|
|
|
// SetWindowLong(appWindow, GWL_STYLE, appFlags | WS_DISABLED);
|
|
|
|
|
//}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//!< show ui to scan button push
|
|
|
|
|
auto scanFunction = [this](const GScanCap& caps) {
|
|
|
|
|
m_pendingXfers = 1;
|
|
|
|
|
m_scanparam.reset(new GScanCap(caps));
|
2020-07-11 10:43:17 +00:00
|
|
|
|
saveGscanCapSetting();
|
2020-06-20 03:01:35 +00:00
|
|
|
|
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));
|
2020-07-11 10:43:17 +00:00
|
|
|
|
saveGscanCapSetting();
|
2020-06-20 03:01:35 +00:00
|
|
|
|
notifyCloseOk();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//!< cancel button push
|
|
|
|
|
auto cancelFunction = [this]() {
|
|
|
|
|
notifyCloseCancel();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
CWnd* parent = guiBridge.get();
|
|
|
|
|
|
|
|
|
|
TwGlue glue = { scanFunction, cancelFunction };
|
|
|
|
|
TwGlue glueUiOnly = { confirmFunction, cancelFunction };
|
|
|
|
|
std::string serialnum = scanner->GetSerialNum();
|
|
|
|
|
std::string hardwareversion = scanner->GetFWVersion();
|
|
|
|
|
guiTwain.reset(new CTwainUI(bUiOnly ? glueUiOnly : glue, *m_scanparam, bUiOnly ? "ȷ<EFBFBD><EFBFBD>" : "ɨ<EFBFBD><EFBFBD>", hardwareversion, serialnum));
|
|
|
|
|
guiTwain->Create(IDD_TWAINUI, parent);
|
2020-08-15 08:42:43 +00:00
|
|
|
|
CRect newRect;
|
|
|
|
|
::GetWindowRect(static_cast<HWND>(ui.parent().raw()), &newRect);
|
2020-08-31 07:44:24 +00:00
|
|
|
|
SetWindowPos(guiTwain->m_hWnd, HWND_TOPMOST, newRect.left + 20, newRect.top + 100, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOACTIVATE);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
guiTwain->ShowWindow(SW_SHOWNORMAL);
|
|
|
|
|
return success();
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-08-31 07:44:24 +00:00
|
|
|
|
void HuagaoDs::DeviceEvent_callback(int eventID, void* usrdata)
|
|
|
|
|
{
|
|
|
|
|
HuagaoDs* This = (HuagaoDs*)usrdata;
|
|
|
|
|
This->onDeviceEvent(eventID);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
//}
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
const BITMAPINFOHEADER* HuagaoDs::header() const noexcept {
|
2020-11-16 10:05:04 +00:00
|
|
|
|
return reinterpret_cast<const BITMAPINFOHEADER*>(bmpData->data() + sizeof(BITMAPFILEHEADER));
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
UInt32 HuagaoDs::bytesPerLine() const noexcept {
|
2020-06-20 03:01:35 +00:00
|
|
|
|
auto dib = header();
|
|
|
|
|
return static_cast<UInt32>(dib->biWidth * dib->biBitCount + 31) / 32 * 4;
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
UInt32 HuagaoDs::bmpSize() const noexcept {
|
2020-11-16 10:05:04 +00:00
|
|
|
|
return static_cast<UInt32>(bmpData->size()) - sizeof(BITMAPFILEHEADER);
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
const char* HuagaoDs::bmpBegin() const noexcept {
|
2020-11-16 10:05:04 +00:00
|
|
|
|
return (const char*)bmpData->cbegin()._Ptr + sizeof(BITMAPFILEHEADER);
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
const char* HuagaoDs::bmpEnd() const noexcept {
|
2020-11-16 10:05:04 +00:00
|
|
|
|
return (const char*)bmpData->cend()._Ptr;
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HuagaoDs::updataGscanCap()
|
|
|
|
|
{
|
2020-06-20 03:01:35 +00:00
|
|
|
|
GscanJsonConfig js;
|
|
|
|
|
GScanCap cfs = js.ReadGscanCap();
|
|
|
|
|
cfs.resolution_native = 200.0f;
|
|
|
|
|
cfs.threshold = 128;
|
2020-08-15 08:42:43 +00:00
|
|
|
|
//FileTools::write_log("D:\\2.txt", "is_autodiscradblank_normal = " + to_string(cfs.is_autodiscradblank_normal) + "is_autodiscradblank_vince =" + to_string(cfs.is_autodiscradblank_vince));
|
2020-07-11 10:43:17 +00:00
|
|
|
|
if (cfs.is_autocrop)
|
|
|
|
|
{
|
|
|
|
|
m_autoboarderdetcet = true;
|
|
|
|
|
m_autosize = (UInt16)AutoSize::Auto;
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
m_scanparam.reset(new GScanCap(cfs));
|
2020-03-11 01:58:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Twpp::Result HuagaoDs::startScan()
|
|
|
|
|
{
|
2020-09-21 01:25:46 +00:00
|
|
|
|
xtfer = 0;
|
2020-11-12 11:42:16 +00:00
|
|
|
|
//FileTools::write_log("D:\\1.txt", "RESET TWAIN TRANSFERED IMAGE COUNT");
|
2020-08-31 07:44:24 +00:00
|
|
|
|
if (!scanner->IsConnected())
|
|
|
|
|
{
|
2020-11-16 10:05:04 +00:00
|
|
|
|
#ifdef LANXUM
|
|
|
|
|
scanner->open(0x31c9, 0x8200);
|
|
|
|
|
#else
|
2020-08-31 07:44:24 +00:00
|
|
|
|
scanner->open(0x064B, 0x7823);
|
2020-11-16 10:05:04 +00:00
|
|
|
|
#endif
|
2020-08-31 07:44:24 +00:00
|
|
|
|
if (!scanner->IsConnected())
|
|
|
|
|
return checkDeviceOnline();
|
|
|
|
|
}
|
2020-06-20 03:01:35 +00:00
|
|
|
|
|
|
|
|
|
scanner->ResetScanner();
|
2020-03-11 01:58:06 +00:00
|
|
|
|
|
2020-05-16 01:59:44 +00:00
|
|
|
|
#ifndef G200
|
2020-06-20 03:01:35 +00:00
|
|
|
|
scanner->clear_hwerror();
|
2020-05-16 01:59:44 +00:00
|
|
|
|
#endif //
|
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
scanner->config_params(*m_scanparam);
|
2020-08-15 08:42:43 +00:00
|
|
|
|
//FileTools::write_log("D:\\2.txt", "is_autodiscradblank_normal = " + to_string(m_scanparam->is_autodiscradblank_normal) + " 222is_autodiscradblank_vince =" + to_string(m_scanparam->is_autodiscradblank_vince));
|
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
if (m_bIndicator) {
|
|
|
|
|
//!< cancel button push
|
|
|
|
|
auto stopFunc = [this]() {
|
2020-08-31 07:44:24 +00:00
|
|
|
|
if(scanner.get())
|
|
|
|
|
scanner->Stop_scan();
|
|
|
|
|
//guiIndicator.reset();//ȡ<><C8A1>ɨ<EFBFBD><C9A8> <20>رս<D8B1><D5BD><EFBFBD>ָʾ<D6B8><CABE>
|
2020-06-20 03:01:35 +00:00
|
|
|
|
if (guiTwain.get()) {
|
|
|
|
|
((CTwainUI*)(guiTwain.get()))->EnableID_OKorID_Cancel(true);
|
|
|
|
|
}
|
2020-08-31 07:44:24 +00:00
|
|
|
|
onDeviceEvent(USER_STOP);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
};
|
2020-08-31 07:44:24 +00:00
|
|
|
|
guiIndicator = new CIndicatorDlg(stopFunc);
|
|
|
|
|
guiIndicator->Create(IDD_INDICATOR, guiTwain.get() ? guiTwain.get() : guiBridge.get());//guiTwain ? guiTwain.get() : guiBridge.get()
|
2020-06-20 03:01:35 +00:00
|
|
|
|
guiIndicator->ShowWindow(SW_SHOWNORMAL);
|
|
|
|
|
}
|
|
|
|
|
scanner->Scanner_StartScan(m_scanparam->scannum);
|
2020-11-16 10:05:04 +00:00
|
|
|
|
if (bmpData->size() > 0)
|
|
|
|
|
{
|
|
|
|
|
bmpData.reset(new std::vector<unsigned char>);
|
|
|
|
|
}
|
2020-06-20 03:01:35 +00:00
|
|
|
|
if (guiTwain.get()) {
|
|
|
|
|
((CTwainUI*)(guiTwain.get()))->EnableID_OKorID_Cancel(false);
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-16 10:05:04 +00:00
|
|
|
|
int retCode = scanner->aquire_bmpdata(*bmpData.get());
|
2020-06-20 03:01:35 +00:00
|
|
|
|
if (retCode != 0) {
|
|
|
|
|
scanner->Set_ErrorCode(0);
|
2020-08-31 07:44:24 +00:00
|
|
|
|
if (guiIndicator)
|
|
|
|
|
guiIndicator->DestroyWindow();
|
|
|
|
|
|
|
|
|
|
//if(guiIndicator.get())
|
|
|
|
|
// guiIndicator.reset();
|
2020-06-20 03:01:35 +00:00
|
|
|
|
if (retCode != -1) {
|
2020-07-07 01:54:19 +00:00
|
|
|
|
//MessageBox(guiTwain ? guiTwain->m_hWnd : NULL, noticeMsgMap[retCode], _T("<22><>ʾ"), MB_SYSTEMMODAL | MB_OK | MB_ICONINFORMATION);
|
|
|
|
|
CString str;
|
|
|
|
|
str.Format(_T("%d"), retCode);
|
2020-11-16 10:05:04 +00:00
|
|
|
|
m_pendingXfers = 0;
|
|
|
|
|
m_memXferYOff = 0;
|
|
|
|
|
m_haveError = true;
|
2020-07-07 01:54:19 +00:00
|
|
|
|
ShellExecute(guiTwain ? guiTwain->m_hWnd : NULL, TEXT("open"), GetHidedlgPath(), str, NULL, SW_HIDE);
|
2020-06-20 03:01:35 +00:00
|
|
|
|
#ifndef G200
|
|
|
|
|
scanner->clear_hwerror();
|
|
|
|
|
#endif //
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (guiTwain.get()) {
|
|
|
|
|
((CTwainUI*)(guiTwain.get()))->EnableID_OKorID_Cancel(true);
|
|
|
|
|
}
|
2020-09-21 01:25:46 +00:00
|
|
|
|
if (retCode == 2)
|
|
|
|
|
return { ReturnCode::Failure, ConditionCode::NoMedia};//<2F><>ֽ
|
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return seqError();
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-16 10:05:04 +00:00
|
|
|
|
if (bmpData->size() > 0) {
|
|
|
|
|
m_haveError = false;
|
2020-06-20 03:01:35 +00:00
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
else {
|
2020-08-15 08:42:43 +00:00
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
if (guiTwain.get()) {
|
|
|
|
|
((CTwainUI*)(guiTwain.get()))->EnableID_OKorID_Cancel(true);
|
|
|
|
|
}
|
|
|
|
|
return seqError();
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-03-11 01:58:06 +00:00
|
|
|
|
|
2020-06-20 03:01:35 +00:00
|
|
|
|
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.WriteJsonArrayToFile(vc, savepath);
|
|
|
|
|
}
|