/*************************************************************************** * Copyright � 2007 TWAIN Working Group: * Adobe Systems Incorporated, AnyDoc Software Inc., Eastman Kodak Company, * Fujitsu Computer Products of America, JFL Peripheral Solutions Inc., * Ricoh Corporation, and Xerox Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the TWAIN Working Group nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY TWAIN Working Group ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TWAIN Working Group BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ /** * @file CTWAINDS_FreeImage.cpp * The main Data Source class. * This class is derived from the Base class describing a TWAIN DS. * @author TWAIN Working Group * @date April 2007 */ #include "stdafx.h" #include "CTWAINDS_FreeImage.h" #include "TWAIN_UI.h" #include #include #include #include #include #include #include "PublicFunc.h" #include "filetools.h" #ifdef TWH_CMP_MSC #include #endif //#include "UI_INI.h" // I found that compiling using the sunfreeware.com stuff on Solaris 9 // required this typedef. This is related to the inclusion of signal.h #if defined (__SVR4) && defined (__sun) typedef union { long double _q; uint32_t _l[4]; } upad128_t; #endif using namespace std; //* Initialize global identiy for this DS. */ TW_IDENTITY CTWAINDS_Base::m_TheIdentity = { 0, // TW_UINT32 Id; Unique number. In Windows, application hWnd { // TW_VERSION Version; Identifies the piece of code 2, // TW_UINT16 MajorNum; Major revision number of the software 1, // TW_UINT16 MinorNum; Incremental revision number of the software TWLG_ENGLISH, // TW_UINT16 Language; e.g. TWLG_SWISSFRENCH TWCY_USA, // TW_UINT16 Country; e.g. TWCY_SWITZERLAND #ifdef __APPLE__ "\p" #endif "2.1.4 " // TW_STR32 Info; e.g. "1.0b3 Beta release" #ifdef _DEBUG " debug" #else " release" #endif #ifdef TWH_32BIT " 32bit" #else " 64bit" #endif }, 2, // TW_UINT16 ProtocolMajor; Application and DS must set to TWON_PROTOCOLMAJOR 1, // TW_UINT16 ProtocolMinor; Application and DS must set to TWON_PROTOCOLMINOR DG_IMAGE | DG_CONTROL | DF_DS2, // TW_UINT32 SupportedGroups; Bit field OR combination of DG_ constants #ifdef __APPLE__ "\p" #endif "HUAGOSCAN", // TW_STR32 Manufacturer; Manufacturer name, e.g. "Hewlett-Packard" #ifdef __APPLE__ "\p" #endif "HUAGOSCAN Hi Series", // TW_STR32 ProductFamily; Product family name, e.g. "ScanJet" #ifdef __APPLE__ "\p" #endif #ifdef G200 "HUAGOSCAN Hi-2800 TWAIN" // TW_STR32 ProductName; Product name, e.g. "ScanJet Plus" #elif defined G300 "HUAGOSCAN G300 TWAIN" #elif defined G400 "HUAGOSCAN G400 TWAIN" //"ZhibenScan XS8100 TWAIN" #endif // G200 }; ////////////////////////////////////////////////////////////////////////////// CTWAINDS_FreeImage::CTWAINDS_FreeImage(TW_IDENTITY AppID) : m_pICAP_FRAMES(0) { b_created = g_CreateSysMutex(); m_AppID = AppID; // Setup our identity fillIdentityStructure(*getIdentity()); m_pGUI = CreateUI(this); isDestroyed = false; } bool CTWAINDS_FreeImage::StoreCapInStream(stringstream& _DsData, TW_UINT16 _unCapID, TW_UINT16 _unCapIdx, TW_UINT16 unContType) { CUST_DS_DATA_ELEMENT* pCapCon = (CUST_DS_DATA_ELEMENT*) new BYTE[sizeof(CUST_DS_DATA_ELEMENT)]; CTWAINContainer* pCap = findCapability(_unCapID); TW_UINT16 unType = pCap->GetItemType(); pCapCon->unItemType = unType; pCapCon->unCapID = _unCapID; pCapCon->unCapIdx = _unCapIdx; pCapCon->unContType = unContType; pCapCon->dwSize = sizeof(CUST_DS_DATA_ELEMENT); if (unContType != TWON_ONEVALUE)//currentlly storing a single value { delete[]pCapCon; return false; } if (typeid(*pCap) == typeid(CTWAINContainerBool)) { CTWAINContainerBool* pfBoolCap = (CTWAINContainerBool*)pCap; bool bVal; if (!pfBoolCap->GetCurrent(bVal)) { delete[]pCapCon; return false; } pCapCon->dwVal[0] = bVal ? 1 : 0; } else if (typeid(*pCap) == typeid(CTWAINContainerInt)) { CTWAINContainerInt* pfIntCap = (CTWAINContainerInt*)pCap; int nVal; if (!pfIntCap->GetCurrent(nVal)) { delete[]pCapCon; return false; } pCapCon->dwVal[0] = nVal; } else if (typeid(*pCap) == typeid(CTWAINContainerFix32)) { CTWAINContainerFix32* pfFix32Cap = (CTWAINContainerFix32*)pCap; float fVal; if (!pfFix32Cap->GetCurrent(fVal)) { delete[]pCapCon; return false; } *((float*)pCapCon->dwVal) = fVal; } else if (typeid(*pCap) == typeid(CTWAINContainerFix32Range)) { CTWAINContainerFix32Range* pfFix32Cap = (CTWAINContainerFix32Range*)pCap; float fVal; if (!pfFix32Cap->GetCurrent(fVal)) { delete[]pCapCon; return false; } *((float*)pCapCon->dwVal) = fVal; } else if (typeid(*pCap) == typeid(CTWAINContainerFrame)) { CTWAINContainerFrame* pfFrameCap = (CTWAINContainerFrame*)pCap; InternalFrame frmVal; if (!pfFrameCap->GetCurrent(frmVal)) { delete[]pCapCon; return false; } CUST_DS_DATA_ELEMENT* pCapCon1 = (CUST_DS_DATA_ELEMENT*) new BYTE[sizeof(CUST_DS_DATA_ELEMENT) + (4 * sizeof(int) - sizeof(DWORD))]; *pCapCon1 = *pCapCon; delete[]pCapCon; pCapCon = pCapCon1; pCapCon->dwSize += (4 * sizeof(int) - sizeof(DWORD)); pCapCon->dwVal[0] = frmVal.nBottom; pCapCon->dwVal[1] = frmVal.nLeft; pCapCon->dwVal[2] = frmVal.nRight; pCapCon->dwVal[3] = frmVal.nTop; } else { delete[]pCapCon; return false; } _DsData.write((char*)pCapCon, pCapCon->dwSize); delete[]pCapCon; return true; } bool CTWAINDS_FreeImage::ReadCapFromStream(stringstream& _DsData, TW_UINT16 _unCapID, TW_UINT16 _unCapIdx) { _DsData.seekg(0, ios_base::beg); DWORD dwSize = sizeof(CUST_DS_DATA_ELEMENT); CUST_DS_DATA_ELEMENT* pCapCon = (CUST_DS_DATA_ELEMENT*) new BYTE[dwSize]; pCapCon->unCapID = -1; pCapCon->unCapIdx = -1; pCapCon->dwSize = 0; while (!_DsData.eof() && (pCapCon->unCapID != _unCapID || pCapCon->unCapIdx != _unCapIdx)) { _DsData.read((char*)pCapCon, sizeof(CUST_DS_DATA_ELEMENT)); if (!_DsData.eof() && pCapCon->dwSize > sizeof(CUST_DS_DATA_ELEMENT)) { if (pCapCon->dwSize > dwSize) { BYTE* pTemp = new BYTE[pCapCon->dwSize]; memcpy(pTemp, pCapCon, sizeof(CUST_DS_DATA_ELEMENT)); delete[]pCapCon; pCapCon = (CUST_DS_DATA_ELEMENT*)pTemp; dwSize = pCapCon->dwSize; } _DsData.read((char*)pCapCon + sizeof(CUST_DS_DATA_ELEMENT), pCapCon->dwSize - sizeof(CUST_DS_DATA_ELEMENT)); } } if (pCapCon->unCapID != _unCapID || pCapCon->unCapIdx != _unCapIdx) { delete[]pCapCon; return false; } CTWAINContainer* pCap = findCapability(_unCapID); TW_UINT16 unType = pCap->GetItemType(); if (unType != pCapCon->unItemType) { delete[]pCapCon; return false; } if (pCapCon->unContType != TWON_ONEVALUE)//currentlly storing a single value { delete[]pCapCon; return false; } bool bRes = true; TW_ONEVALUE conVal; conVal.ItemType = pCapCon->unItemType; conVal.Item = pCapCon->dwVal[0]; if (typeid(*pCap) == typeid(CTWAINContainerBool)) { bRes = validateCapabilitySet(_unCapID, TWON_ONEVALUE, (BYTE*)& conVal) != TWRC_FAILURE; if (bRes) { CTWAINContainerBool* pfBoolCap = (CTWAINContainerBool*)pCap; bRes = pfBoolCap->SetCurrent(pCapCon->dwVal[0] != 0); } } else if (typeid(*pCap) == typeid(CTWAINContainerInt)) { bRes = validateCapabilitySet(_unCapID, TWON_ONEVALUE, (BYTE*)& conVal) != TWRC_FAILURE; if (bRes) { CTWAINContainerInt* pfIntCap = (CTWAINContainerInt*)pCap; bRes = pfIntCap->SetCurrent(pCapCon->dwVal[0]); } } else if (typeid(*pCap) == typeid(CTWAINContainerFix32)) { bRes = validateCapabilitySet(_unCapID, TWON_ONEVALUE, (BYTE*)& conVal) != TWRC_FAILURE; if (bRes) { CTWAINContainerFix32* pfFix32Cap = (CTWAINContainerFix32*)pCap; bRes = pfFix32Cap->SetCurrent(*(float*)pCapCon->dwVal); } } else if (typeid(*pCap) == typeid(CTWAINContainerFix32Range)) { bRes = validateCapabilitySet(_unCapID, TWON_ONEVALUE, (BYTE*)& conVal) != TWRC_FAILURE; if (bRes) { CTWAINContainerFix32Range* pfFix32Cap = (CTWAINContainerFix32Range*)pCap; bRes = pfFix32Cap->SetCurrent(*(float*)pCapCon->dwVal); } } else if (typeid(*pCap) == typeid(CTWAINContainerFrame)) { InternalFrame frmVal; frmVal.nBottom = pCapCon->dwVal[0]; frmVal.nLeft = pCapCon->dwVal[1]; frmVal.nRight = pCapCon->dwVal[2]; frmVal.nTop = pCapCon->dwVal[3]; bool bConstrained; ConstrainFrameToScanner(frmVal, bConstrained); CTWAINContainerFrame* pfFrameCap = (CTWAINContainerFrame*)pCap; bRes = pfFrameCap->Set(frmVal); } else { bRes = false; } delete[]pCapCon; return bRes; } bool CTWAINDS_FreeImage::StoreCustomDSdata(stringstream& DsData) { bool bResult = true; bResult = bResult && StoreCapInStream(DsData, CAP_FEEDERENABLED, 0, TWON_ONEVALUE); bResult = bResult && StoreCapInStream(DsData, CAP_DUPLEXENABLED, 0, TWON_ONEVALUE); bResult = bResult && StoreCapInStream(DsData, CAP_AUTOFEED, 0, TWON_ONEVALUE); bResult = bResult && StoreCapInStream(DsData, ICAP_BITDEPTH, 0, TWON_ONEVALUE); bResult = bResult && StoreCapInStream(DsData, ICAP_BITORDER, 0, TWON_ONEVALUE); bResult = bResult && StoreCapInStream(DsData, ICAP_COMPRESSION, 0, TWON_ONEVALUE); bResult = bResult && StoreCapInStream(DsData, ICAP_FRAMES, 0, TWON_ONEVALUE); bResult = bResult && StoreCapInStream(DsData, ICAP_IMAGEFILEFORMAT, 0, TWON_ONEVALUE); bResult = bResult && StoreCapInStream(DsData, ICAP_PIXELFLAVOR, 0, TWON_ONEVALUE); bResult = bResult && StoreCapInStream(DsData, ICAP_PIXELTYPE, 0, TWON_ONEVALUE); bResult = bResult && StoreCapInStream(DsData, ICAP_PLANARCHUNKY, 0, TWON_ONEVALUE); bResult = bResult && StoreCapInStream(DsData, ICAP_SUPPORTEDSIZES, 0, TWON_ONEVALUE); bResult = bResult && StoreCapInStream(DsData, ICAP_ORIENTATION, 0, TWON_ONEVALUE); bResult = bResult && StoreCapInStream(DsData, ICAP_UNITS, 0, TWON_ONEVALUE); bResult = bResult && StoreCapInStream(DsData, ICAP_XRESOLUTION, 0, TWON_ONEVALUE); bResult = bResult && StoreCapInStream(DsData, ICAP_YRESOLUTION, 0, TWON_ONEVALUE); bResult = bResult && StoreCapInStream(DsData, ICAP_THRESHOLD, 0, TWON_ONEVALUE); bResult = bResult && StoreCapInStream(DsData, ICAP_CONTRAST, 0, TWON_ONEVALUE); bResult = bResult && StoreCapInStream(DsData, ICAP_BRIGHTNESS, 0, TWON_ONEVALUE); bResult = bResult && StoreCapInStream(DsData, ICAP_GAMMA, 0, TWON_ONEVALUE); bResult = bResult && StoreCapInStream(DsData, CUSTCAP_LONGDOCUMENT, 0, TWON_ONEVALUE); return bResult; } bool CTWAINDS_FreeImage::ReadCustomDSdata(stringstream& DsData) { // When adding to Capabiltiy remember the order of operations // Some capabilities are dependent on others. // see: http://www.twain.org/docs/CapOrderForWeb.PDF bool bResult = true; bResult = bResult && ReadCapFromStream(DsData, CUSTCAP_LONGDOCUMENT, 0); bResult = bResult && ReadCapFromStream(DsData, ICAP_BITORDER, 0); bResult = bResult && ReadCapFromStream(DsData, CAP_FEEDERENABLED, 0); bResult = bResult && ReadCapFromStream(DsData, CAP_DUPLEXENABLED, 0); bResult = bResult && ReadCapFromStream(DsData, CAP_AUTOFEED, 0); bResult = bResult && ReadCapFromStream(DsData, ICAP_UNITS, 0); bResult = bResult && ReadCapFromStream(DsData, ICAP_PIXELTYPE, 0); bResult = bResult && ReadCapFromStream(DsData, ICAP_BITDEPTH, 0); bResult = bResult && ReadCapFromStream(DsData, ICAP_XRESOLUTION, 0); bResult = bResult && ReadCapFromStream(DsData, ICAP_YRESOLUTION, 0); bResult = bResult && ReadCapFromStream(DsData, ICAP_PIXELFLAVOR, 0); bResult = bResult && ReadCapFromStream(DsData, ICAP_PLANARCHUNKY, 0); bResult = bResult && ReadCapFromStream(DsData, ICAP_THRESHOLD, 0); bResult = bResult && ReadCapFromStream(DsData, ICAP_IMAGEFILEFORMAT, 0); bResult = bResult && ReadCapFromStream(DsData, ICAP_COMPRESSION, 0); bResult = bResult && ReadCapFromStream(DsData, ICAP_CONTRAST, 0); bResult = bResult && ReadCapFromStream(DsData, ICAP_BRIGHTNESS, 0); bResult = bResult && ReadCapFromStream(DsData, ICAP_GAMMA, 0); bResult = bResult && ReadCapFromStream(DsData, ICAP_SUPPORTEDSIZES, 0); bResult = bResult && ReadCapFromStream(DsData, ICAP_ORIENTATION, 0); bResult = bResult && ReadCapFromStream(DsData, ICAP_FRAMES, 0); return bResult; } ////////////////////////////////////////////////////////////////////////////// TW_INT16 CTWAINDS_FreeImage::Initialize() { // When adding to Capabiltiy remember the order of operations // Some capabilities are dependent on others. // see: http://www.twain.org/docs/CapOrderForWeb.PDF // setup the supported independant caps CTWAINContainerInt* pnCap = 0; CTWAINContainerBool* pbCap = 0; CTWAINContainerString* pstrCap = 0; CTWAINContainerFix32* pfixCap = 0; m_IndependantCapMap[CAP_SUPPORTEDCAPS] = new CTWAINContainerInt(CAP_SUPPORTEDCAPS, TWTY_UINT16, TWON_ARRAY, TWQC_GETS, TWON_ARRAY, TWON_ARRAY); if (NULL == (pnCap = dynamic_cast(m_IndependantCapMap[CAP_SUPPORTEDCAPS])) || !pnCap->Add(CAP_DEVICEONLINE) || !pnCap->Add(CAP_INDICATORS) || !pnCap->Add(CAP_ENABLEDSUIONLY) || !pnCap->Add(CAP_PAPERDETECTABLE) || !pnCap->Add(CAP_FEEDERENABLED) || !pnCap->Add(CAP_FEEDERLOADED) || !pnCap->Add(CAP_DUPLEX) || !pnCap->Add(CAP_DUPLEXENABLED) || !pnCap->Add(CAP_AUTOFEED) || !pnCap->Add(CAP_SUPPORTEDCAPS) || !pnCap->Add(CAP_UICONTROLLABLE) || !pnCap->Add(CAP_XFERCOUNT) || !pnCap->Add(ICAP_BITDEPTH) || !pnCap->Add(ICAP_BITORDER) || !pnCap->Add(ICAP_COMPRESSION) || !pnCap->Add(ICAP_FRAMES) || !pnCap->Add(ICAP_MAXFRAMES) || !pnCap->Add(ICAP_IMAGEFILEFORMAT) || !pnCap->Add(ICAP_PHYSICALHEIGHT) || !pnCap->Add(ICAP_PHYSICALWIDTH) || !pnCap->Add(ICAP_PIXELFLAVOR) || !pnCap->Add(ICAP_PIXELTYPE) || !pnCap->Add(ICAP_PLANARCHUNKY) || !pnCap->Add(ICAP_SUPPORTEDSIZES) || !pnCap->Add(ICAP_ORIENTATION) || !pnCap->Add(ICAP_UNITS) || !pnCap->Add(ICAP_XFERMECH) || !pnCap->Add(ICAP_XRESOLUTION) || !pnCap->Add(ICAP_YRESOLUTION) || !pnCap->Add(ICAP_THRESHOLD) || !pnCap->Add(ICAP_CONTRAST) || !pnCap->Add(ICAP_BRIGHTNESS) || !pnCap->Add(ICAP_GAMMA) || !pnCap->Add(CAP_CUSTOMINTERFACEGUID) || !pnCap->Add(CUSTCAP_LONGDOCUMENT) || !pnCap->Add(CUSTCAP_DOCS_IN_ADF) || !pnCap->Add(CAP_CUSTOMDSDATA) //后加 || !pnCap->Add(CAP_SERIALNUMBER) || !pnCap->Add(0x8025)//固件版本号 || !pnCap->Add(ICAP_AUTOMATICCROPUSESFRAME)//自动裁切 || !pnCap->Add(ICAP_AUTODISCARDBLANKPAGES)//自动丢弃空白页 || !pnCap->Add(ICAP_AUTOMATICCOLORENABLED)//自动颜色识别 || !pnCap->Add(ICAP_AUTOMATICLENGTHDETECTION)//长度检测 || !pnCap->Add(ICAP_AUTOBRIGHT)//自动亮度 || !pnCap->Add(ICAP_AUTOMATICDESKEW)//自动纠偏 || !pnCap->Add(ICAP_FILTER)//除色 || !pnCap->Add(0x8005)//背面旋转180 || !pnCap->Add(0x8004)//填充黑框 || !pnCap->Add(0x8018)//去除穿孔 || !pnCap->Add(0x8026)//多流除红 || !pnCap->Add(0x8092)//去除穿孔所占幅面占比 //硬件协议 #ifdef G200 || !pnCap->Add(0x8006)//歪斜检测 || !pnCap->Add(0x8021)//歪斜程度 || !pnCap->Add(0x8090)//装订检测 #endif // G200 || !pnCap->Add(CAP_DOUBLEFEEDDETECTION)//双张检测 || !pnCap->Add(0x8091)//自动丢弃空白页(发票) ) { cerr << "Could not create CAP_SUPPORTEDCAPS" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } m_IndependantCapMap[ICAP_COMPRESSION] = new CTWAINContainerInt(ICAP_COMPRESSION, TWTY_UINT16, TWON_ENUMERATION); if (NULL == (pnCap = dynamic_cast(m_IndependantCapMap[ICAP_COMPRESSION])) || !pnCap->Add(TWCP_NONE, true)) { cerr << "Could not create ICAP_COMPRESSION" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } m_IndependantCapMap[ICAP_PLANARCHUNKY] = new CTWAINContainerInt(ICAP_PLANARCHUNKY, TWTY_UINT16, TWON_ENUMERATION); if (NULL == (pnCap = dynamic_cast(m_IndependantCapMap[ICAP_PLANARCHUNKY])) || !pnCap->Add(TWPC_CHUNKY, true)) /// @todo support TWPC_PLANAR // || !pnCap->Add(TWPC_PLANAR) { cerr << "Could not create ICAP_PLANARCHUNKY" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } m_IndependantCapMap[ICAP_UNITS] = new CTWAINContainerInt(ICAP_UNITS, TWTY_UINT16, TWON_ENUMERATION); if (NULL == (pnCap = dynamic_cast(m_IndependantCapMap[ICAP_UNITS])) || !pnCap->Add(TWUN_INCHES, true) || !pnCap->Add(TWUN_PIXELS) || !pnCap->Add(TWUN_CENTIMETERS) || !pnCap->Add(TWUN_PICAS) || !pnCap->Add(TWUN_POINTS) || !pnCap->Add(TWUN_TWIPS)) { cerr << "Could not create ICAP_UNITS" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } m_IndependantCapMap[ICAP_XFERMECH] = new CTWAINContainerInt(ICAP_XFERMECH, TWTY_UINT16, TWON_ONEVALUE); if (NULL == (pnCap = dynamic_cast(m_IndependantCapMap[ICAP_XFERMECH])) || !pnCap->Add(TWSX_FILE) || !pnCap->Add(TWSX_MEMORY) || !pnCap->Add(TWSX_NATIVE, true) ) { cerr << "Could not create ICAP_XFERMECH" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } m_IndependantCapMap[ICAP_PIXELTYPE] = new CTWAINContainerInt(ICAP_PIXELTYPE, TWTY_UINT16, TWON_ENUMERATION); if (NULL == (pnCap = dynamic_cast(m_IndependantCapMap[ICAP_PIXELTYPE])) || !pnCap->Add(TWPT_BW) || !pnCap->Add(TWPT_GRAY) || !pnCap->Add(TWPT_RGB, true)) { cerr << "Could not create ICAP_PIXELTYPE" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } m_IndependantCapMap[CAP_UICONTROLLABLE] = new CTWAINContainerBool(CAP_UICONTROLLABLE, (m_AppID.SupportedGroups & DF_APP2) != 0, TWQC_GETS); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[CAP_UICONTROLLABLE])) || !pbCap->Add(TRUE, true)) { cerr << "Could not create CAP_UICONTROLLABLE" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } m_IndependantCapMap[CAP_ENABLEDSUIONLY] = new CTWAINContainerBool(CAP_ENABLEDSUIONLY, (m_AppID.SupportedGroups & DF_APP2) != 0, TWQC_GETS); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[CAP_ENABLEDSUIONLY])) || !pbCap->Add(TRUE, true)) { cerr << "Could not create CAP_ENABLEDSUIONLY" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } m_IndependantCapMap[CAP_XFERCOUNT] = new CTWAINContainerInt(CAP_XFERCOUNT, TWTY_INT16, TWON_ONEVALUE); if (NULL == (pnCap = dynamic_cast(m_IndependantCapMap[CAP_XFERCOUNT])) || !pnCap->Add(TWON_DONTCARE32, true)) { cerr << "Could not create CAP_XFERCOUNT" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } m_IndependantCapMap[ICAP_BITORDER] = new CTWAINContainerInt(ICAP_BITORDER, TWTY_UINT16, TWON_ENUMERATION); if (NULL == (pnCap = dynamic_cast(m_IndependantCapMap[ICAP_BITORDER])) || !pnCap->Add(TWBO_LSBFIRST, true) || !pnCap->Add(TWBO_MSBFIRST)) { cerr << "Could not create ICAP_BITORDER" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } m_IndependantCapMap[ICAP_IMAGEFILEFORMAT] = new CTWAINContainerInt(ICAP_IMAGEFILEFORMAT, TWTY_UINT16, TWON_ENUMERATION); if (NULL == (pnCap = dynamic_cast(m_IndependantCapMap[ICAP_IMAGEFILEFORMAT])) || !pnCap->Add(TWFF_BMP, true) || !pnCap->Add(TWFF_TIFF)) { cerr << "Could not create ICAP_IMAGEFILEFORMAT" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } SSTRCPY(m_CurFileExferName, sizeof(m_CurFileExferName), "sample.bmp"); SSTRCPY(m_DefFileExferName, sizeof(m_DefFileExferName), "sample.bmp"); m_IndependantCapMap[ICAP_PIXELFLAVOR] = new CTWAINContainerInt(ICAP_PIXELFLAVOR, TWTY_UINT16, TWON_ENUMERATION); if (NULL == (pnCap = dynamic_cast(m_IndependantCapMap[ICAP_PIXELFLAVOR])) || !pnCap->Add(TWPF_CHOCOLATE, true)) { cerr << "Could not create ICAP_PIXELFLAVOR" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } //TWSS_B5 //文稿类型 m_IndependantCapMap[ICAP_SUPPORTEDSIZES] = new CTWAINContainerInt(ICAP_SUPPORTEDSIZES, TWTY_UINT16, TWON_ENUMERATION); if (NULL == (pnCap = dynamic_cast(m_IndependantCapMap[ICAP_SUPPORTEDSIZES])) #ifdef G200 || !pnCap->Add(TWSS_NONE) || !pnCap->Add(TWSS_A3) || !pnCap->Add(TWSS_A4, true) || !pnCap->Add(60)//A4R || !pnCap->Add(TWSS_A5) || !pnCap->Add(61)//A5R || !pnCap->Add(TWSS_A6) || !pnCap->Add(62)//A6R || !pnCap->Add(TWSS_B4) || !pnCap->Add(2)//B5 || !pnCap->Add(70)//B5R || !pnCap->Add(TWSS_B6)//B6 || !pnCap->Add(71)//B6横向 || !pnCap->Add(TWSS_USLETTER) || !pnCap->Add(80)//LETTER横向 || !pnCap->Add(81)//Double LetterR || !pnCap->Add(TWSS_USLEGAL) || !pnCap->Add(TWSS_MAXSIZE)//长文稿 #elif defined G300 || !pnCap->Add(TWSS_NONE) || !pnCap->Add(TWSS_A4, true) || !pnCap->Add(TWSS_A5) || !pnCap->Add(TWSS_A6) || !pnCap->Add(2)//B5 || !pnCap->Add(TWSS_B6)//B6 || !pnCap->Add(TWSS_USLETTER) || !pnCap->Add(TWSS_USLEGAL) #elif defined G400 || !pnCap->Add(TWSS_NONE) || !pnCap->Add(TWSS_A3) || !pnCap->Add(TWSS_A4, true) || !pnCap->Add(60)//A4R || !pnCap->Add(TWSS_A5) || !pnCap->Add(61)//A5R || !pnCap->Add(TWSS_A6) || !pnCap->Add(62)//A6R || !pnCap->Add(TWSS_B4) || !pnCap->Add(2)//B5 || !pnCap->Add(70)//B5R || !pnCap->Add(TWSS_B6)//B6 || !pnCap->Add(71)//B6横向 || !pnCap->Add(TWSS_USLETTER) || !pnCap->Add(80)//LETTER横向 || !pnCap->Add(81)//Double LetterR || !pnCap->Add(TWSS_USLEGAL) #endif // G200 ) { cerr << "Could not create ICAP_SUPPORTEDSIZES" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } //图像旋转 m_IndependantCapMap[ICAP_ORIENTATION] = new CTWAINContainerInt(ICAP_ORIENTATION, TWTY_UINT16, TWON_ONEVALUE); if (NULL == (pnCap = dynamic_cast(m_IndependantCapMap[ICAP_ORIENTATION])) || !pnCap->Add(TWOR_PORTRAIT, true) || !pnCap->Add(TWOR_ROT90) || !pnCap->Add(TWOR_ROT180) || !pnCap->Add(TWOR_ROT270) || !pnCap->Add(TWOR_AUTOTEXT)) { cerr << "Could not create ICAP_ORIENTATION" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } m_IndependantCapMap[CAP_DEVICEONLINE] = new CTWAINContainerBool(CAP_DEVICEONLINE, (m_AppID.SupportedGroups & DF_APP2) != 0, TWQC_GETS); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[CAP_DEVICEONLINE])) || !pbCap->Add(TRUE, true) || !pbCap->Add(FALSE)) { cerr << "Could not create CAP_DEVICEONLINE" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } m_IndependantCapMap[CAP_INDICATORS] = new CTWAINContainerBool(CAP_INDICATORS, (m_AppID.SupportedGroups & DF_APP2) != 0, TWQC_ALL); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[CAP_INDICATORS])) || !pbCap->Add(TRUE, true) || !pbCap->Add(FALSE)) { cerr << "Could not create CAP_INDICATORS" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } m_IndependantCapMap[ICAP_MAXFRAMES] = new CTWAINContainerInt(ICAP_MAXFRAMES, TWTY_UINT16, TWON_ONEVALUE, TWQC_ALL); if (NULL == (pnCap = dynamic_cast(m_IndependantCapMap[ICAP_MAXFRAMES])) || !pnCap->Add(1, true)) { cerr << "Could not create ICAP_MAXFRAMES" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } m_IndependantCapMap[CAP_FEEDERENABLED] = new CTWAINContainerBool(CAP_FEEDERENABLED, (m_AppID.SupportedGroups & DF_APP2) != 0, TWQC_ALL); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[CAP_FEEDERENABLED])) || !pbCap->Add(FALSE) || !pbCap->Add(TRUE, true)) { cerr << "Could not create CAP_FEEDERENABLED" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } m_IndependantCapMap[CAP_DUPLEX] = new CTWAINContainerInt(CAP_DUPLEX, TWTY_UINT16, TWON_ONEVALUE, TWQC_GETS); if (NULL == (pnCap = dynamic_cast(m_IndependantCapMap[CAP_DUPLEX])) || !pnCap->Add(TWDX_1PASSDUPLEX, true)) { cerr << "Could not create CAP_DUPLEX" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } m_IndependantCapMap[CAP_DUPLEXENABLED] = new CTWAINContainerBool(CAP_DUPLEXENABLED, (m_AppID.SupportedGroups & DF_APP2) != 0, TWQC_ALL); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[CAP_DUPLEXENABLED])) || !pbCap->Add(TRUE) || !pbCap->Add(FALSE, true)) { cerr << "Could not create CAP_DUPLEXENABLED" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } m_IndependantCapMap[CAP_FEEDERLOADED] = new CTWAINContainerBool(CAP_FEEDERLOADED, (m_AppID.SupportedGroups & DF_APP2) != 0, TWQC_GETS); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[CAP_FEEDERLOADED])) || !pbCap->Add(TRUE) || !pbCap->Add(FALSE, true)) { cerr << "Could not create CAP_FEEDERLOADED" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } m_IndependantCapMap[CAP_AUTOFEED] = new CTWAINContainerBool(CAP_AUTOFEED, (m_AppID.SupportedGroups & DF_APP2) != 0, TWQC_ALL); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[CAP_AUTOFEED])) || !pbCap->Add(TRUE, true) || !pbCap->Add(FALSE)) { cerr << "Could not create CAP_AUTOFEED" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } m_IndependantCapMap[CAP_PAPERDETECTABLE] = new CTWAINContainerBool(CAP_PAPERDETECTABLE, (m_AppID.SupportedGroups & DF_APP2) != 0, TWQC_GETS); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[CAP_PAPERDETECTABLE])) || !pbCap->Add(TRUE, true)) { cerr << "Could not create CAP_PAPERDETECTABLE" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } m_IndependantCapMap[CUSTCAP_LONGDOCUMENT] = new CTWAINContainerBool(CUSTCAP_LONGDOCUMENT, (m_AppID.SupportedGroups & DF_APP2) != 0, TWQC_ALL); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[CUSTCAP_LONGDOCUMENT])) || !pbCap->Add(TRUE) || !pbCap->Add(FALSE, true)) { cerr << "Could not create CUSTCAP_LONGDOCUMENT" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } m_IndependantCapMap[CUSTCAP_DOCS_IN_ADF] = new CTWAINContainerInt(CUSTCAP_DOCS_IN_ADF, TWTY_UINT16, TWON_ONEVALUE, TWQC_ALL); if (NULL == (pnCap = dynamic_cast(m_IndependantCapMap[CUSTCAP_DOCS_IN_ADF])) || !pnCap->Add(m_Scanner.GetMaxPagesInADF())) { cerr << "Could not create CUSTCAP_DOCS_IN_ADF" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } m_IndependantCapMap[CAP_CUSTOMDSDATA] = new CTWAINContainerBool(CAP_CUSTOMDSDATA, (m_AppID.SupportedGroups & DF_APP2) != 0, TWQC_GETS); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[CAP_CUSTOMDSDATA])) || !pbCap->Add(TRUE, true)) { cerr << "Could not create CAP_CUSTOMDSDATA" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } // setup dependant caps if (NULL == (m_BitDepthMap[TWPT_BW] = new CTWAINContainerInt(ICAP_BITDEPTH, TWTY_UINT16, TWON_ONEVALUE)) || !m_BitDepthMap[TWPT_BW]->Add(1, true)) { cerr << "Could not create ICAP_BITDEPTH" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } if (NULL == (m_BitDepthMap[TWPT_GRAY] = new CTWAINContainerInt(ICAP_BITDEPTH, TWTY_UINT16, TWON_ONEVALUE)) || !m_BitDepthMap[TWPT_GRAY]->Add(8, true)) { cerr << "Could not create ICAP_BITDEPTH" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } if (NULL == (m_BitDepthMap[TWPT_RGB] = new CTWAINContainerInt(ICAP_BITDEPTH, TWTY_UINT16, TWON_ONEVALUE)) || !m_BitDepthMap[TWPT_RGB]->Add(24, true)) { cerr << "Could not create ICAP_BITDEPTH" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } m_IndependantCapMap[CAP_CUSTOMINTERFACEGUID] = new CTWAINContainerString(CAP_CUSTOMINTERFACEGUID, TWTY_STR255, TWON_ONEVALUE, TWQC_GETS); if (NULL == (pstrCap = dynamic_cast(m_IndependantCapMap[CAP_CUSTOMINTERFACEGUID])) || !pstrCap->Add(kCUSTOMDSGUI, true)) { cerr << "Could not create CAP_CUSTOMINTERFACEGUID" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } FLOAT_RANGE fRange; fRange.fCurrentValue = 10.0f; fRange.fMaxValue = 50.0f; fRange.fMinValue = 0.0f; fRange.fStepSize = 1.0f; m_IndependantCapMap[ICAP_GAMMA] = new CTWAINContainerFix32Range(ICAP_GAMMA, fRange, TWQC_ALL); if (NULL == dynamic_cast(m_IndependantCapMap[ICAP_GAMMA])) { cerr << "Could not create ICAP_GAMMA" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } fRange.fCurrentValue = 128.0f; fRange.fMaxValue = 255.0f; fRange.fMinValue = 0.0f; fRange.fStepSize = 1.0f; m_IndependantCapMap[ICAP_THRESHOLD] = new CTWAINContainerFix32Range(ICAP_THRESHOLD, fRange, TWQC_ALL); if (NULL == dynamic_cast(m_IndependantCapMap[ICAP_THRESHOLD])) { cerr << "Could not create ICAP_THRESHOLD" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } fRange.fCurrentValue = 0.0f; fRange.fMaxValue = 1000.0f; fRange.fMinValue = -1000.0f; fRange.fStepSize = 1.0f; m_IndependantCapMap[ICAP_CONTRAST] = new CTWAINContainerFix32Range(ICAP_CONTRAST, fRange, TWQC_ALL); if (NULL == dynamic_cast(m_IndependantCapMap[ICAP_CONTRAST])) { cerr << "Could not create ICAP_CONTRAST" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } fRange.fCurrentValue = 0.0f; fRange.fMaxValue = 1000.0f; fRange.fMinValue = -1000.0f; fRange.fStepSize = 1.0f; m_IndependantCapMap[ICAP_BRIGHTNESS] = new CTWAINContainerFix32Range(ICAP_BRIGHTNESS, fRange, TWQC_ALL); if (NULL == dynamic_cast(m_IndependantCapMap[ICAP_BRIGHTNESS])) { cerr << "Could not create ICAP_BRIGHTNESS" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } // expressed internally as pixels per inch m_IndependantCapMap[ICAP_XRESOLUTION] = new CTWAINContainerFix32(ICAP_XRESOLUTION, TWON_ONEVALUE, TWQC_ALL); if (NULL == (pfixCap = dynamic_cast(m_IndependantCapMap[ICAP_XRESOLUTION])) //|| !pfixCap->Add(50) || !pfixCap->Add(100.0f) || !pfixCap->Add(150.0f) || !pfixCap->Add(200.0f, true) || !pfixCap->Add(240.0f) || !pfixCap->Add(300.0f)) //|| !pfixCap->Add(500) //|| !pfixCap->Add(600)) { cerr << "Could not create ICAP_XRESOLUTION" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } // expressed internally as pixels per inch m_IndependantCapMap[ICAP_YRESOLUTION] = new CTWAINContainerFix32(ICAP_YRESOLUTION, TWON_ONEVALUE, TWQC_ALL); if (NULL == (pfixCap = dynamic_cast(m_IndependantCapMap[ICAP_YRESOLUTION])) //|| !pfixCap->Add(50) || !pfixCap->Add(100.0f) || !pfixCap->Add(150.0f) || !pfixCap->Add(200.0f, true) || !pfixCap->Add(240.0f) || !pfixCap->Add(300.0f)) //|| !pfixCap->Add(500) //|| !pfixCap->Add(600)) { cerr << "Could not create ICAP_YRESOLUTION" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } // expressed internally as 1000 pixels per inch /// @todo Get physical dimentions from scanner /// @todo Add seperate dimentions for ADF and Flatbed // Flatbed - A4 letter paper // ConvertUnits(29.7f, TWUN_CENTIMETERS, TWUN_INCHES, 1000); // ConvertUnits(21.0f, TWUN_CENTIMETERS, TWUN_INCHES, 1000); if (NULL == (m_IndependantCapMap[ICAP_PHYSICALWIDTH] = new CTWAINContainerFix32(ICAP_PHYSICALWIDTH, TWON_ONEVALUE, TWQC_GETS)) || !(dynamic_cast(m_IndependantCapMap[ICAP_PHYSICALWIDTH]))->Add(8.5, true)) { cerr << "Could not create ICAP_PHYSICALWIDTH" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } if (NULL == (m_IndependantCapMap[ICAP_PHYSICALHEIGHT] = new CTWAINContainerFix32(ICAP_PHYSICALHEIGHT, TWON_ONEVALUE, TWQC_GETS)) || !(dynamic_cast(m_IndependantCapMap[ICAP_PHYSICALHEIGHT]))->Add(14.0, true)) { cerr << "Could not create ICAP_PHYSICALHEIGHT" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } // setup the ICAP_FRAMES // expressed internally as 1000 pixels per inch // Currently only supports one frame see: ICAP_MAXFRAMES if (NULL == (m_pICAP_FRAMES = new CTWAINContainerFrame(ICAP_FRAMES, TWON_ENUMERATION, TWQC_ALL)) || !m_pICAP_FRAMES->Add(0, 0, 2338, 3307, true) //|| !m_pICAP_FRAMES->Add(0, 0, 1653, 2338) //|| !m_pICAP_FRAMES->Add(0, 0, 2338, 1653) //|| !m_pICAP_FRAMES->Add(0, 0, 1165, 1653) //|| !m_pICAP_FRAMES->Add(0, 0, 1653, 1165) //|| !m_pICAP_FRAMES->Add(0, 0, 826, 1165) //|| !m_pICAP_FRAMES->Add(0, 0, 1165, 826) //|| !m_pICAP_FRAMES->Add(0, 0, 2023, 2866) //|| !m_pICAP_FRAMES->Add(0, 0, 1433, 2023) //|| !m_pICAP_FRAMES->Add(0, 0, 2203, 1433) //|| !m_pICAP_FRAMES->Add(0, 0, 1007, 1433) //|| !m_pICAP_FRAMES->Add(0, 0, 1433, 1007) //|| !m_pICAP_FRAMES->Add(0, 0, 1700, 2200) //|| !m_pICAP_FRAMES->Add(0, 0, 2200, 1700) //|| !m_pICAP_FRAMES->Add(0, 0, 2200, 3400) //|| !m_pICAP_FRAMES->Add(0, 0, 1700, 2800) //|| !m_pICAP_FRAMES->Add(0, 0, 2338, 3307) //|| !m_pICAP_FRAMES->Add(0, 0, 2338, 6614) ) { cerr << "Could not create ICAP_FRAMES" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } int unit; float Xres, Yres; if (getCurrentUnits(unit, Xres, Yres) == TWRC_SUCCESS) { m_pICAP_FRAMES->setCurrentUnits(unit, Xres, Yres); } else { cerr << "Could not getCurrentUnits" << endl; setConditionCode(TWCC_BUMMER); return TWRC_FAILURE; } /*一下为后加协议 2018-11-15 ByPeng*/ //扫描仪序列号 m_IndependantCapMap[CAP_SERIALNUMBER] = new CTWAINContainerString(CAP_SERIALNUMBER, TWTY_STR255, TWON_ONEVALUE, TWQC_GETS); if (NULL == (pstrCap = dynamic_cast(m_IndependantCapMap[CAP_SERIALNUMBER])) || !pstrCap->Add("G20018000000", true))//m_Scanner.getSerialNum() { cerr << "Could not create CAP_SERIALNUMBER" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } //扫描仪固件版本号 m_IndependantCapMap[0x8025] = new CTWAINContainerString(0x8025, TWTY_STR255, TWON_ONEVALUE, TWQC_GETS); if (NULL == (pstrCap = dynamic_cast(m_IndependantCapMap[0x8025])) || !pstrCap->Add("51000000", true)) { cerr << "Could not create Get FWVersion" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } //自动裁切 m_IndependantCapMap[ICAP_AUTOMATICCROPUSESFRAME] = new CTWAINContainerBool(ICAP_AUTOMATICCROPUSESFRAME, (m_AppID.SupportedGroups & DF_APP2) != 0, TWQC_ALL); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[ICAP_AUTOMATICCROPUSESFRAME])) || !pbCap->Add(TRUE) || !pbCap->Add(FALSE, true)) { cerr << "Could not create ICAP_AUTOMATICCROPUSESFRAME" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } //自动丢弃空白页(通用) m_IndependantCapMap[ICAP_AUTODISCARDBLANKPAGES] = new CTWAINContainerBool(ICAP_AUTODISCARDBLANKPAGES, (m_AppID.SupportedGroups & DF_APP2) != 0, TWQC_ALL); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[ICAP_AUTODISCARDBLANKPAGES])) || !pbCap->Add(TRUE) || !pbCap->Add(FALSE, true)) { cerr << "Could not create ICAP_AUTODISCARDBLANKPAGES" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } //自动丢弃空白页(发票) m_IndependantCapMap[0x8091] = new CTWAINContainerBool(0x8091, TWON_ONEVALUE, TWQC_ALL); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[0x8091])) || !pbCap->Add(TRUE) || !pbCap->Add(FALSE, true)) { cerr << "Could not create 发票" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } //填充黑框 m_IndependantCapMap[0x8004] = new CTWAINContainerBool(0x8004, TWON_ONEVALUE, TWQC_ALL); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[0x8004])) || !pbCap->Add(TRUE) || !pbCap->Add(FALSE, true)) { cerr << "Could not create ICAP_AUTODISCARDBLANKPAGES" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } //自动颜色识别 m_IndependantCapMap[ICAP_AUTOMATICCOLORENABLED] = new CTWAINContainerBool(ICAP_AUTOMATICCOLORENABLED, (m_AppID.SupportedGroups & DF_APP2) != 0, TWQC_ALL); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[ICAP_AUTOMATICCOLORENABLED])) || !pbCap->Add(TRUE) || !pbCap->Add(FALSE, true)) { cerr << "Could not create ICAP_AUTOMATICCOLORENABLED" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } //自动长度检测 m_IndependantCapMap[ICAP_AUTOMATICLENGTHDETECTION] = new CTWAINContainerBool(ICAP_AUTOMATICLENGTHDETECTION, (m_AppID.SupportedGroups & DF_APP2) != 0, TWQC_ALL); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[ICAP_AUTOMATICLENGTHDETECTION])) || !pbCap->Add(TRUE) || !pbCap->Add(FALSE, true)) { cerr << "Could not create ICAP_AUTOMATICCOLORENABLED" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } //自动亮度 m_IndependantCapMap[ICAP_AUTOBRIGHT] = new CTWAINContainerBool(ICAP_AUTOBRIGHT, (m_AppID.SupportedGroups & DF_APP2) != 0, TWQC_ALL); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[ICAP_AUTOBRIGHT])) || !pbCap->Add(TRUE) || !pbCap->Add(FALSE, true)) { cerr << "Could not create ICAP_AUTOBRIGHT" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } //自动纠偏 m_IndependantCapMap[ICAP_AUTOMATICDESKEW] = new CTWAINContainerBool(ICAP_AUTOMATICDESKEW, (m_AppID.SupportedGroups & DF_APP2) != 0, TWQC_ALL); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[ICAP_AUTOMATICDESKEW])) || !pbCap->Add(TRUE) || !pbCap->Add(FALSE, true)) { cerr << "Could not create ICAP_AUTOMATICDESKEW" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } //除色与颜色增强 m_IndependantCapMap[ICAP_FILTER] = new CTWAINContainerInt(ICAP_FILTER, TWTY_UINT16, TWON_ONEVALUE); if (NULL == (pnCap = dynamic_cast(m_IndependantCapMap[ICAP_FILTER])) || !pnCap->Add(0, true)//不除色 || !pnCap->Add(1)//除红色 || !pnCap->Add(2)//除绿色 || !pnCap->Add(3)//除蓝色 || !pnCap->Add(4)//红色增强 || !pnCap->Add(5)//绿色增强 || !pnCap->Add(6))//蓝色增强 //|| !pfixCap->Add(7))//自定义颜色增强 { cerr << "Could not create ICAP_FILTER" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } //背面旋转180 m_IndependantCapMap[0x8005] = new CTWAINContainerBool(0x8005, TWON_ONEVALUE, TWQC_ALL); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[0x8005])) || !pbCap->Add(TRUE) || !pbCap->Add(FALSE, true)) { cerr << "Could not create Bcak Flip 180 Dgr" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } //去除穿孔 m_IndependantCapMap[0x8018] = new CTWAINContainerBool(0x8018, TWON_ONEVALUE, TWQC_ALL); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[0x8018])) || !pbCap->Add(TRUE) || !pbCap->Add(FALSE, true)) { cerr << "Could not create OutHole" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } //去除穿孔占幅面比例 fRange.fCurrentValue = 10.0f; fRange.fMaxValue = 50.0f; fRange.fMinValue = 1.0f; fRange.fStepSize = 1.0f; m_IndependantCapMap[0x8092] = new CTWAINContainerFix32Range(0x8092, fRange, TWQC_ALL); if (NULL == dynamic_cast(m_IndependantCapMap[0x8092])) { cerr << "Could not create Outhole ration" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } #ifdef G200 //歪斜检测 m_IndependantCapMap[0x8006] = new CTWAINContainerBool(0x8006, TWON_ONEVALUE, TWQC_ALL); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[0x8006])) || !pbCap->Add(TRUE) || !pbCap->Add(FALSE, true)) { cerr << "Could not create Skew DETECT" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } //歪斜检测范围 fRange.fCurrentValue = 3.0f; fRange.fMaxValue = 5.0f; fRange.fMinValue = 1.0f; fRange.fStepSize = 1.0f; m_IndependantCapMap[0x8021] = new CTWAINContainerFix32Range(0x8021, fRange, TWQC_ALL); if (NULL == dynamic_cast(m_IndependantCapMap[0x8021])) { cerr << "Could not create CAP Skew Range" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } //装订检测 m_IndependantCapMap[0x8090] = new CTWAINContainerBool(0x8090, TWON_ONEVALUE, TWQC_ALL); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[0x8090])) || !pbCap->Add(TRUE) || !pbCap->Add(FALSE, true)) { cerr << "Could not create Double Feeded DETECT" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } #endif // G200 //双张检测 m_IndependantCapMap[CAP_DOUBLEFEEDDETECTION] = new CTWAINContainerBool(CAP_DOUBLEFEEDDETECTION, (m_AppID.SupportedGroups & DF_APP2) != 0, TWQC_ALL); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[CAP_DOUBLEFEEDDETECTION])) || !pbCap->Add(TRUE) || !pbCap->Add(FALSE, true)) { cerr << "Could not create Double Feeded DETECT" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } //多流除红 m_IndependantCapMap[0x8026] = new CTWAINContainerBool(0x8026, TWON_ONEVALUE, TWQC_ALL); if (NULL == (pbCap = dynamic_cast(m_IndependantCapMap[0x8026])) || !pbCap->Add(TRUE) || !pbCap->Add(FALSE, true)) { cerr << "Could not create multi output" << endl; setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } return TWRC_SUCCESS; } ////////////////////////////////////////////////////////////////////////////// CTWAINDS_FreeImage::~CTWAINDS_FreeImage() { DestroyUI(m_pGUI); // free all resources belonging to m_IndependantCapMap TWAINCapabilitiesMap_int::iterator cur_int = m_BitDepthMap.begin(); while (cur_int != m_BitDepthMap.end()) { delete cur_int->second; cur_int++; } if (m_pICAP_FRAMES) { delete m_pICAP_FRAMES; } m_pICAP_FRAMES = 0; g_CloseSysMutexRun();//关闭互斥锁 return; } ////////////////////////////////////////////////////////////////////////////// void CTWAINDS_FreeImage::fillIdentityStructure(TW_IDENTITY& _idStruct) { _idStruct = m_TheIdentity; } ////////////////////////////////////////////////////////////////////////////// TW_INT16 CTWAINDS_FreeImage::getImageInfo(pTW_IMAGEINFO _pImageInfo) { TW_INT16 twrc = TWRC_SUCCESS; memset(_pImageInfo, 0, sizeof(TW_IMAGEINFO)); // Only valid in state 6 and 7(State 7 only after receiving TWRC_XFERDONE) if (dsState_XferReady > m_CurrentState) { setConditionCode(TWCC_SEQERROR); return TWRC_FAILURE; } // Get the actual values used by the scanner. SFreeImage* settings = m_Scanner.getSetting(); int nUnit = TWUN_INCHES; CTWAINContainerInt* pnCap = 0; if (0 == (pnCap = dynamic_cast(findCapability(ICAP_UNITS))) || false == pnCap->GetCurrent(nUnit)) { setConditionCode(TWCC_OPERATIONERROR); return TWRC_FAILURE; } _pImageInfo->XResolution = FloatToFIX32(ConvertUnits(float(settings->m_fXResolution), nUnit, TWUN_INCHES, settings->m_fXResolution)); _pImageInfo->YResolution = FloatToFIX32(ConvertUnits(float(settings->m_fYResolution), nUnit, TWUN_INCHES, settings->m_fYResolution)); _pImageInfo->ImageWidth = m_Scanner.m_nSourceWidth; _pImageInfo->ImageLength = m_Scanner.m_nSourceHeight; //XdPrint("_pImageInfo->ImageWidth = %d, aaa\n",_pImageInfo->ImageWidth); // Our sample scanner only does one combination for each PixelType. switch (settings->m_nPixelType) { case TWPT_BW: _pImageInfo->PixelType = TWPT_BW; _pImageInfo->BitsPerPixel = 1; _pImageInfo->SamplesPerPixel = 1; _pImageInfo->BitsPerSample[0] = 1; break; case TWPT_GRAY: _pImageInfo->PixelType = TWPT_GRAY; _pImageInfo->BitsPerPixel = 8; _pImageInfo->SamplesPerPixel = 1; _pImageInfo->BitsPerSample[0] = 8; break; case TWPT_RGB: _pImageInfo->PixelType = TWPT_RGB; _pImageInfo->BitsPerPixel = 24; _pImageInfo->SamplesPerPixel = 3; _pImageInfo->BitsPerSample[0] = 8; _pImageInfo->BitsPerSample[1] = 8; _pImageInfo->BitsPerSample[2] = 8; break; } _pImageInfo->Planar = FALSE; _pImageInfo->Compression = TWCP_NONE; return twrc; } ////////////////////////////////////////////////////////////////////////////// TW_INT16 CTWAINDS_FreeImage::openDS(pTW_IDENTITY _pOrigin) { if (b_created == FALSE) { return TWRC_FAILURE; } if (!m_Scanner.getDeviceOnline()) { std::string cvt = StringToUtf("请检查电源或USB通信是否正常!"); std::string notify = StringToUtf("提示"); MyMessageBox((TCHAR*)cvt.c_str(), (TCHAR*)notify.c_str(), MB_SYSTEMMODAL | MB_OK | MB_ICONINFORMATION); return TWRC_FAILURE; } TW_INT16 ret = TWRC_SUCCESS; // this basic version of the DS only supports one connection from the DSM if (m_App.Id != 0) { setConditionCode(TWCC_MAXCONNECTIONS); return TWRC_FAILURE; } if (dsState_Loaded != m_CurrentState) { setConditionCode(TWCC_SEQERROR); return TWRC_FAILURE; } // store the pointer of the originating scan requestor. m_App = *_pOrigin; m_DocumentNumber = 0; m_PageNumber = 0; if (!m_Scanner.resetScanner()) { setConditionCode(TWCC_BUMMER); assert(0); ret = TWRC_FAILURE; } else { m_CurrentState = dsState_Open; } JsonConfig js; CONFIGPARAMS configParams = js.ReadDefaultConfig(); bool ss = UpdateCapsFromConfig(configParams); return ret; } ////////////////////////////////////////////////////////////////////////////// TW_INT16 CTWAINDS_FreeImage::closeDS() { // check if ok to return success // Must be in state 4 //if (!isDestroyed)//m_CurrentState==dsState_Enabled //{ //m_pGUI->DestroyTWAINGUI(); //XdPrint("closeDS m_pGUI->DestroyTWAINGUI() \n"); //// // allow the scanners caps to be writeable again because we are moving back //// // to state 4. If this source had a UI, it would be lowered at this time. //m_Scanner.Unlock(); //m_CurrentState = dsState_Open; //isDestroyed=true; //} //else if (dsState_Open != m_CurrentState) { setConditionCode(TWCC_SEQERROR); return TWRC_FAILURE; } memset(&m_App, 0, sizeof(m_App)); //FileTools::write_log("D:/1.txt"," Close DS "); XdPrint(" CloseDS !\n"); return TWRC_SUCCESS; } ////////////////////////////////////////////////////////////////////////////// TW_INT16 CTWAINDS_FreeImage::enableDS(pTW_USERINTERFACE _pData) { if (b_created == FALSE)//Twain被其他程序占用 { return TWRC_FAILURE; } if (dsState_Open != m_CurrentState) { setConditionCode(TWCC_SEQERROR); //FileTools::write_log("D:/1.txt","enableDS dsState_Open != m_CurrentState"); return TWRC_FAILURE; } m_CurrentState = dsState_Enabled; m_bCanceled = false; //set pending xfers to whatever the user configured for XferCount //int Count = TWON_DONTCARE32; //CTWAINContainerInt *pnCap = dynamic_cast(findCapability(CAP_XFERCOUNT)); //if (pnCap) //{ // pnCap->GetCurrent(Count); //} //m_Xfers.Count = Count; //stringstream ss; //ss<(findCapability(CAP_INDICATORS)); bIndicators = FALSE; if (pbCap) { pbCap->GetCurrent(bIndicators); } if (m_pGUI->DisplayTWAINGUI(*_pData, false, bIndicators) != TWRC_SUCCESS) { //A user interface is not supported as of right now because we are //in text mode. m_CurrentState = dsState_Open; setConditionCode(TWCC_SEQERROR); //FileTools::write_log("D:/1.txt","enableDS m_pGUI->DisplayTWAINGUI(*_pData, false, bIndicators) != TWRC_SUCCESS"); return TWRC_FAILURE; } if (FALSE == _pData->ShowUI) { // Update the scanner with the latest negotiated caps //if (!updateScannerFromCaps()) //{ // cerr << "ds: There was an error while prepping the image for scanning" << endl; // setConditionCode(TWCC_BADVALUE); // return TWRC_FAILURE; //} // The application will move to state 5 after this triplet which means that // no more capabilities can be set until we are brought back to state 4. m_Scanner.Lock(); // Because there is no user interface, there isn't anything to show here. // But, at this point, the application is not allowed to set any more // capabilities. This means that we can do any initializations we // need in order to prepare for the next few calls and the scan. // get the scanner to load the image so that image info calls can be done if (!StartScanning())//!m_Scanner.acquireImage() { cerr << "ds: There was an error while trying to get scanner to acquire image" << endl; m_CurrentState = dsState_Open; setConditionCode(TWCC_SEQERROR); //FileTools::write_log("D:/1.txt","enableDS !StartScanning()"); return TWRC_FAILURE; } if (!DoXferReadyEvent()) { m_CurrentState = dsState_Open; setConditionCode(TWCC_SEQERROR); //FileTools::write_log("D:/1.txt","enableDS !DoXferReadyEvent()"); return TWRC_FAILURE; } } //CTWAINContainerBool *pbCap = dynamic_cast(findCapability(CAP_INDICATORS)); //bIndicators = FALSE; //if (pbCap) //{ // pbCap->GetCurrent(bIndicators); //} //if (m_pGUI->DisplayTWAINGUI(*_pData, false, bIndicators) != TWRC_SUCCESS) //{ //// // A user interface is not supported as of right now because we are //// // in text mode. // m_CurrentState = dsState_Open; // setConditionCode(TWCC_OPERATIONERROR); // return TWRC_FAILURE; //} return TWRC_SUCCESS; } ////////////////////////////////////////////////////////////////////////////// TW_INT16 CTWAINDS_FreeImage::enableDSOnly(pTW_USERINTERFACE _pData) { //if (b_created==FALSE)//Twain被其他程序占用 //{ // //FileTools::write_log("D:/1.txt","b_created==FALSE"); // return TWRC_FAILURE; //} if (dsState_Open != m_CurrentState) { setConditionCode(TWCC_SEQERROR); //FileTools::write_log("D:/1.txt","dsState_Open != m_CurrentState"); return TWRC_FAILURE; } m_CurrentState = dsState_Enabled; if (m_pGUI->DisplayTWAINGUI(*_pData, true, false) != TWRC_SUCCESS) { // A user interface is not supported as of right now because we are // in text mode. //FileTools::write_log("D:/1.txt","m_pGUI->DisplayTWAINGUI(*_pData, true, false) != TWRC_SUCCESS"); m_CurrentState = dsState_Open; setConditionCode(TWCC_OPERATIONERROR); return TWRC_FAILURE; } return TWRC_SUCCESS; } ////////////////////////////////////////////////////////////////////////////// TW_INT16 CTWAINDS_FreeImage::disableDS(pTW_USERINTERFACE _pData) { if (dsState_Enabled != m_CurrentState) { //FileTools::write_log("D:/1.txt"," disableDS dsState_Enabled != m_CurrentState"); setConditionCode(TWCC_SEQERROR); return TWRC_FAILURE; } //if (!isDestroyed) //{ m_pGUI->DestroyTWAINGUI(); // isDestroyed=true; //} // allow the scanners caps to be writeable again because we are moving back // to state 4. If this source had a UI, it would be lowered at this time. m_Scanner.Unlock(); // There is no UI in this text interface so there is nothing // to do here. m_CurrentState = dsState_Open; XdPrint(" disableDS !\n"); return TWRC_SUCCESS; } ////////////////////////////////////////////////////////////////////////////// TW_INT16 CTWAINDS_FreeImage::getMemoryXfer(pTW_SETUPMEMXFER _pData) { // valid to call for 4, 5, & 6 if (!(dsState_Open == m_CurrentState || dsState_Enabled == m_CurrentState || dsState_XferReady == m_CurrentState)) { setConditionCode(TWCC_SEQERROR); return TWRC_FAILURE; } // Validate the pointer... if (_pData == 0) { setConditionCode(TWCC_BADVALUE); return TWRC_FAILURE; } // Min is the physical width at highest res and hishest bits/pixel count TW_UINT32 bytes = (TW_UINT32)BYTES_PERLINE_ALIGN4(8.5 * 600, 24); _pData->MinBufSize = bytes; // chose 64k because this is a typical sweet spot for most real world scanners // (max transfer size for SCSI read of typical SCSI devices) _pData->MaxBufSize = MAX((TW_UINT32)64 * 1024, bytes);//bytes; _pData->Preferred = MAX((TW_UINT32)64 * 1024, bytes);//bytes; // Update the min based on current settings. if (m_CurrentState == dsState_XferReady) { // If we have an image ready then we can use that info to get the memory requirements //get the number of bytes per line we'll need for this image, and make sure it's DWORD-aligned _pData->MinBufSize = BYTES_PERLINE_ALIGN4(m_ImageInfo.ImageWidth, m_ImageInfo.BitsPerPixel); } else { // calculate the min based on the current settings int nBitDepth = 24; float fXResolution = 600.0f; float fWidth = 8.5f * fXResolution; CTWAINContainerInt* pnCap = 0; CTWAINContainerFix32* pfCap = 0; InternalFrame frame; if (0 == (pnCap = dynamic_cast(findCapability(ICAP_BITDEPTH)))) { cerr << "Could not get ICAP_BITDEPTH" << endl; setConditionCode(TWCC_BUMMER); return TWRC_FAILURE; } else { pnCap->GetCurrent(nBitDepth); } if (0 == (pfCap = dynamic_cast(findCapability(ICAP_XRESOLUTION)))) { cerr << "Could not get ICAP_XRESOLUTION" << endl; setConditionCode(TWCC_BUMMER); return TWRC_FAILURE; } else { pfCap->GetCurrent(fXResolution); } if (!m_pICAP_FRAMES->GetCurrent(frame)) { cerr << "Could not get ICAP_FRAMES" << endl; setConditionCode(TWCC_BUMMER); return TWRC_FAILURE; } else { // Get the scanning window by converting from our internal units to pixels. TW_FRAME TWframe = frame.AsTW_FRAME(TWUN_PIXELS, fXResolution, fXResolution); fWidth = FIX32ToFloat(TWframe.Right) - FIX32ToFloat(TWframe.Left); } _pData->MinBufSize = (TW_UINT32)BYTES_PERLINE_ALIGN4(fWidth, nBitDepth); } return TWRC_SUCCESS; } ////////////////////////////////////////////////////////////////////////////// TW_INT16 CTWAINDS_FreeImage::processEvent(pTW_EVENT _pEvent) { TW_UINT16 twRc = TWRC_SUCCESS; if (dsState_Enabled > m_CurrentState) { setConditionCode(TWCC_SEQERROR); return TWRC_FAILURE; } if (0 == _pEvent) { setConditionCode(TWCC_BADVALUE); return TWRC_FAILURE; } if (m_pGUI && m_pGUI->processEvent(_pEvent))//hImageDlg && IsDialogMessage(hImageDlg, (LPMSG)(((pTW_EVENT)pData)->pEvent))) { twRc = TWRC_DSEVENT; // The source should, for proper form, return a MSG_NULL for // all Windows messages processed by the Data Source _pEvent->TWMessage = MSG_NULL; } else { // notify the application that the source did not // consume this message twRc = TWRC_NOTDSEVENT; _pEvent->TWMessage = MSG_NULL; } return twRc; } static int sendnum = 0; ////////////////////////////////////////////////////////////////////////////// TW_INT16 CTWAINDS_FreeImage::transfer() { TW_INT16 twrc = TWRC_SUCCESS; //if (bIndicators) //{ // m_pGUI->UpdateProgress(true,' ',0,""); //} getImageInfo(&m_ImageInfo); //CString str; //str.Format("%d",++sendnum); //string ss((LPCTSTR)str); //FileTools::write_log("D:\\1.txt",ss); if (m_bCanceled) { m_bCanceled = false; return TWRC_CANCEL; } if (dsState_XferReady != m_CurrentState) { setConditionCode(TWCC_SEQERROR); return TWRC_FAILURE; } m_nDestScanLine = 0; static int xfer = 0; //This is for know image size. if (m_ImageInfo.ImageWidth > 0 && m_ImageInfo.ImageLength > 0) { //DWORD nDestBytesPerRow = BYTES_PERLINE(m_ImageInfo.ImageWidth, m_ImageInfo.BitsPerPixel); //DWORD nImageSize = nDestBytesPerRow * m_ImageInfo.ImageLength; DWORD nDestBytesPerRow = BYTES_PERLINE(m_ImageInfo.ImageWidth, m_ImageInfo.BitsPerPixel); //XdPrint("nDestBytesPerRow = %d, BitsPerPixel= %d , m_ImageInfo.ImageWidth = %d\n", nDestBytesPerRow, m_ImageInfo.BitsPerPixel, m_ImageInfo.ImageWidth); DWORD nImageSize = nDestBytesPerRow * m_ImageInfo.ImageLength; //If we had a previous image then get rid of it. if (m_hImageData) { _DSM_Free(m_hImageData); } m_hImageData = _DSM_Alloc(nImageSize); if (!m_hImageData) { setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } TW_MEMREF pData = _DSM_LockMemory(m_hImageData); BYTE* pImageData = (BYTE*)pData; DWORD dwRead; DWORD dwReceived; //memcpy(pImageData, pImageData, nImageSize); do { dwRead = nImageSize;//MIN(64000, nImageSize) / nDestBytesPerRow * //nDestBytesPerRow; dwReceived = 0; if (!m_Scanner.getScanStrip(pImageData, dwRead, dwReceived))//|| //dwReceived != dwReceived / nDestBytesPerRow * nDestBytesPerRow { //No more data to recieve fill the rest break; } pImageData += dwReceived; nImageSize -= dwReceived; } while (nImageSize > 0 && twrc == TWRC_SUCCESS); _DSM_UnlockMemory(m_hImageData); } else { /// @todo Unknow paper size // for unknow paper size need to use reallocate and keep transfering and adding to image data. setConditionCode(TWCC_CAPUNSUPPORTED); return TWRC_FAILURE; } if (twrc == TWRC_FAILURE) { setConditionCode(TWCC_BADVALUE); } return twrc; } ////////////////////////////////////////////////////////////////////////////// TW_INT16 CTWAINDS_FreeImage::endXfer(pTW_PENDINGXFERS _pXfers) { //static int aa=0; //XdPrint("inter times %d\n",aa); //aa++; //FileTools::write_log("D:/1.txt"," 1"); TW_INT16 twrc = TWRC_SUCCESS; if (!(dsState_XferReady == m_CurrentState || dsState_Xferring == m_CurrentState)) { setConditionCode(TWCC_SEQERROR); return TWRC_FAILURE; } if (m_Xfers.Count != TW_UINT16(TWON_DONTCARE16)) { --m_Xfers.Count; } bool rs = m_Scanner.isImageQueueEmpty(); //XdPrint("empty %d \n",rs==true?1:0); if (rs) { m_Xfers.Count = 0; //FileTools::write_log("D:/1.txt"," rs: m_Xfers.Count==0"); } if (m_bCanceled) { m_bCanceled = false; m_Xfers.Count = 0; //FileTools::write_log("D:/1.txt"," m_bCanceled: m_Xfers.Count==0"); } if (0 != m_Xfers.Count) { // Check to see if autofeed is turned on if so automaticly go get next image. CTWAINContainerBool* pbCap = dynamic_cast(findCapability(CAP_AUTOFEED)); bool bAutoFeed = FALSE; if (pbCap) { pbCap->GetCurrent(bAutoFeed); } if (bAutoFeed) { // More images are requested, go to scan and try to get the next // image in pre-emption of the app asking for it if (!m_Scanner.acquireImage(false)) { if (m_Scanner.isImageQueueEmpty()) { m_Xfers.Count = 0; //MessageBox(NULL,"_pXfers ==0 ","1",MB_OK); //FileTools::write_log("D:/1.txt"," (m_Scanner.isImageQueueEmpty: m_Xfers.Count==0"); //cerr << "ds: There was an error while prepping the image for scanning" << endl; //setConditionCode(TWCC_BUMMER); //twrc = TWRC_FAILURE; } } } } else { m_Scanner.Unlock(); } m_CurrentState = dsState_Enabled; if (_pXfers == 0) { //FileTools::write_log("D:/1.txt"," (_pXfers: m_Xfers.Count==0"); setConditionCode(TWCC_BADVALUE); // Did everyting but return the currect count. return TWRC_CHECKSTATUS; } *_pXfers = m_Xfers; if (0 != m_Xfers.Count) { m_CurrentState = dsState_XferReady; } else { if (bIndicators) { //FileTools::write_log("D:/1.txt"," (bIndicators: HIDDEN"); m_pGUI->UpdateProgress(false, '0', 0, "0"); } } return twrc; } ////////////////////////////////////////////////////////////////////////////// TW_INT16 CTWAINDS_FreeImage::getXfer(pTW_PENDINGXFERS _pXfers) { TW_INT16 twrc = TWRC_SUCCESS; if (dsState_XferReady != m_CurrentState) { setConditionCode(TWCC_SEQERROR); return TWRC_FAILURE; } if (_pXfers == 0) { setConditionCode(TWCC_BADVALUE); // Did everyting but return the currect count. return TWRC_CHECKSTATUS; } *_pXfers = m_Xfers; return twrc; } ////////////////////////////////////////////////////////////////////////////// TW_INT16 CTWAINDS_FreeImage::resetXfer(pTW_PENDINGXFERS _pXfers) { TW_INT16 twrc = TWRC_SUCCESS; if (dsState_Loaded == m_CurrentState) { setConditionCode(TWCC_SEQERROR); return TWRC_FAILURE; } m_Xfers.Count = 0; m_CurrentState = dsState_Enabled; m_Scanner.Unlock(); if (_pXfers == 0) { setConditionCode(TWCC_BADVALUE); return TWRC_FAILURE; } *_pXfers = m_Xfers; m_Scanner.StopScan();//扫描仪停止并清空图像队列 return twrc; } ////////////////////////////////////////////////////////////////////////////// bool CTWAINDS_FreeImage::UpdateCapsFromConfig(CONFIGPARAMS pConfig) { int nVal; float fVal; bool bret = true; // Set to false if anything fails bool bVal = false; CTWAINContainerInt* pnCap = 0; CTWAINContainerBool* pbCap = false; CTWAINContainerFix32* pfCap = 0; CTWAINContainerFix32Range* pfRCap = 0; DWORD index = -1; //FileTools::write_log("D:/1.txt",) if (0 == (pnCap = dynamic_cast(findCapability(ICAP_PIXELTYPE)))) { cerr << "Could not get ICAP_PIXELTYPE" << endl; bret = false; } else { bret = pnCap->SetCurrent(pConfig.Pixtype); } if (0 == (pnCap = dynamic_cast(findCapability(ICAP_SUPPORTEDSIZES)))) { cerr << "Could not get ICAP_PIXELTYPE" << endl; bret = false; } else { bret = pnCap->SetCurrent(pConfig.PaperSize); } if (0 == (pbCap = dynamic_cast(findCapability(CAP_DUPLEXENABLED)))) { cerr << "Could not get ICAP_PIXELTYPE" << endl; bret = false; } else { bret = pbCap->SetCurrent(pConfig.Duplex == 0 ? FALSE : TRUE); } if (0 == (pnCap = dynamic_cast(findCapability(ICAP_ORIENTATION)))) { cerr << "Could not get ICAP_ORIENTATION" << endl; bret = false; } else { bret = pnCap->SetCurrent(pConfig.Orentation == 4 ? TWOR_AUTOTEXT : pConfig.Orentation); } if (0 == (pnCap = dynamic_cast(findCapability(ICAP_FILTER)))) { cerr << "Could not get ICAP_FILTER" << endl; bret = false; } else { bret = pnCap->SetCurrent(pConfig.Filter); } if (0 == (pfCap = dynamic_cast(findCapability(ICAP_XRESOLUTION)))) { cerr << "Could not get ICAP_XRESOLUTION" << endl; bret = false; } else { //pfCap->SetCurrent(pConfig->wDPI); bret = pfCap->SetCurrent((float)pConfig.Resolution); } // Y resolution the same. if (0 == (pfCap = dynamic_cast(findCapability(ICAP_YRESOLUTION)))) { cerr << "Could not get ICAP_YRESOLUTION" << endl; bret = false; } else { //pfCap->SetCurrent(pConfig->wDPI); bret = pfCap->SetCurrent(pConfig.Resolution); } if (0 == (pfRCap = dynamic_cast(findCapability(ICAP_CONTRAST)))) { cerr << "Could not get ICAP_CONTRAST" << endl; bret = false; } else { float value_Contrast = GetContrast(pConfig.Contrast); bret = pfRCap->SetCurrent(value_Contrast); } if (0 == (pfRCap = dynamic_cast(findCapability(ICAP_BRIGHTNESS)))) { cerr << "Could not get ICAP_BRIGHTNESS" << endl; bret = false; } else { bret = pfRCap->SetCurrent(pConfig.Brightness); } // Y resolution the same. if (0 == (pfRCap = dynamic_cast(findCapability(ICAP_GAMMA)))) { cerr << "Could not get ICAP_GAMMA" << endl; bret = false; } else { bret = pfRCap->SetCurrent(pConfig.Gamma / 10.0); } if (0 == (pbCap = dynamic_cast(findCapability(ICAP_AUTOMATICCROPUSESFRAME)))) { cerr << "Could not get ICAP_AUTOMATICCROPUSESFRAME" << endl; bret = bret = false; } else { bool temp = (pConfig.PaperSize) == TWSS_NONE; bret = pbCap->SetCurrent(temp); } //填充黑框 if (0 == (pbCap = dynamic_cast(findCapability(0x8004)))) { cerr << "Could not get ICAP_AUTOMATICCROPUSESFRAME" << endl; bret = false; } else { bret = pbCap->SetCurrent(pConfig.EnFillBlack); } if (0 == (pbCap = dynamic_cast(findCapability(ICAP_AUTODISCARDBLANKPAGES)))) { cerr << "Could not get ICAP_AUTODISCARDBLANKPAGES" << endl; bret = false; } else { bool temp = (pConfig.Duplex) == 2; bret = pbCap->SetCurrent(temp); } if (0 == (pbCap = dynamic_cast(findCapability(0x8091)))) { cerr << "Could not get ICAP_AUTODISCARDBLANKPAGES" << endl; bret = false; } else { bool temp = (pConfig.Duplex) == 3; bret = pbCap->SetCurrent(temp); } if (0 == (pbCap = dynamic_cast(findCapability(ICAP_AUTOMATICDESKEW)))) { cerr << "Could not get ICAP_AUTOMATICDESKEW" << endl; bret = false; } else { bret = pbCap->SetCurrent(pConfig.EnAutoDescrew); } if (0 == (pbCap = dynamic_cast(findCapability(0x8005))))//背面旋转180 { cerr << "Could not get CAP_SKREWDETECT" << endl; bret = false; } else { bret = pbCap->SetCurrent(pConfig.EnBackRotate180); } if (0 == (pbCap = dynamic_cast(findCapability(0x8006))))//歪斜检测 { cerr << "Could not get ICAP_AUTOMATICDESKEW" << endl; bret = false; } else { bret = pbCap->SetCurrent(pConfig.EnScrewDetect); } if (0 == (pbCap = dynamic_cast(findCapability((CAP_DOUBLEFEEDDETECTION))))) { cerr << "Could not get CAP_DOUBLEFEEDDETECTION" << endl; bret = false; } else { bret = pbCap->SetCurrent(pConfig.EnUltrasonicDetect); } #ifdef G200 //歪斜检测等级 if (0 == (pfRCap = dynamic_cast(findCapability(0x8021)))) { cerr << "Could not get CAP_SKREWDETECTLEVEL" << endl; bret = false; } else { bret = pfRCap->SetCurrent(pConfig.ScrewDetectLevel); } //装订检测 if (0 == (pbCap = dynamic_cast(findCapability(0x8090)))) { cerr << "Could not get CAP_STAPLEDETECT" << endl; bret = false; } else { bret = pbCap->SetCurrent(pConfig.EnBindingDetect); } #endif // G200 //扫描张数 if (0 == (pnCap = dynamic_cast(findCapability(CAP_XFERCOUNT)))) { //XdPrint("updateScannerFromCaps CAP_XFERCOUNT Error"); bret = false; } else { bret = pnCap->SetCurrent(pConfig.ScanCount); } //去除穿孔 if (0 == (pbCap = dynamic_cast(findCapability(0x8018)))) { bret = false; } else { pbCap->SetCurrent(pConfig.EnOutHole ? true : false); int aa = 2; } //去除穿孔占幅面比例 if (0 == (pfRCap = dynamic_cast(findCapability(0x8092)))) { bret = false; } else { pfRCap->SetCurrent(pConfig.OutHoleRatio); } //多流除红 if (0 == (pbCap = dynamic_cast(findCapability(0x8026)))) { bret = false; } else { pbCap->SetCurrent(pConfig.EnMultiOutPutR); } return bret; } std::string CTWAINDS_FreeImage::GetSerialNum() { return m_Scanner.getSerialNum(); } std::string CTWAINDS_FreeImage::GetFWVerison() { return m_Scanner.getFWVersion(); } bool CTWAINDS_FreeImage::IsImageQueueEmpty() { return m_Scanner.isImageQueueEmpty(); } ////////////////////////////////////////////////////////////////////////////// bool CTWAINDS_FreeImage::updateScannerFromCaps() { int nVal; float fVal; bool bret = true; // Set to false if anything fails bool bVal = false; SFreeImage* settings; // Get current before updating settings = m_Scanner.getSetting(); CTWAINContainerInt* pnCap = 0; CTWAINContainerFix32* pfCap = 0; CTWAINContainerFix32Range* pfRCap = 0; //后加 CTWAINContainerBool* pbCap = false; if (0 == (pnCap = dynamic_cast(findCapability(ICAP_PIXELTYPE)))) { cerr << "Could not get ICAP_PIXELTYPE" << endl; bret = false; } else { bret = pnCap->GetCurrent(nVal); settings->m_nPixelType = nVal; if (nVal == 2) { settings->m_HardWareParams.PixType = TWPT_RGB; } else { settings->m_HardWareParams.PixType = TWPT_GRAY; } } if (0 == (pnCap = dynamic_cast(findCapability(ICAP_SUPPORTEDSIZES)))) { cerr << "Could not get ICAP_PIXELTYPE" << endl; bret = false; } else { bret = pnCap->GetCurrent(nVal); settings->m_HardWareParams.PaperType = nVal; //CString sss; //sss.Format("m_HardWareParams.PaperType is %d",settings->m_HardWareParams.PaperType); //std::string sbuffer = sss.GetBuffer(); //FileTools::write_log("D:/1.txt","get " + sbuffer); } if (0 == (pbCap = dynamic_cast(findCapability(CAP_DUPLEXENABLED)))) { cerr << "Could not get ICAP_PIXELTYPE" << endl; bret = false; } else { bret = pbCap->GetCurrent(bVal); settings->m_bDuplex = bVal; } if (0 == (pnCap = dynamic_cast(findCapability(ICAP_ORIENTATION)))) { cerr << "Could not get ICAP_PIXELTYPE" << endl; bret = false; } else { bret = pnCap->GetCurrent(nVal); settings->m_wRotation = nVal == TWOR_AUTOTEXT ? 4 : nVal;; } if (0 == (pnCap = dynamic_cast(findCapability(ICAP_FILTER)))) { cerr << "Could not get ICAP_PIXELTYPE" << endl; bret = false; } else { bret = pnCap->GetCurrent(nVal); //settings->m_nFilter = nVal; if (nVal != 0) { m_Scanner.m_HardWareParams.PixType = TWPT_RGB; } if (nVal <= 3) { if(nVal == 0) { settings->m_nFilter = 3; } else { settings->m_nFilter = nVal - 1; } settings->m_nEnhance_color = 0; } else { settings->m_nFilter = 3;//不除色 settings->m_nEnhance_color = nVal - 3; } } // X resolution the same. if (0 == (pfCap = dynamic_cast(findCapability(ICAP_XRESOLUTION)))) { cerr << "Could not get ICAP_XRESOLUTION" << endl; bret = false; } else { bret = pfCap->GetCurrent(fVal); settings->m_fXResolution = fVal; settings->m_HardWareParams.Resolution = 200; } // Y resolution the same. if (0 == (pfCap = dynamic_cast(findCapability(ICAP_YRESOLUTION)))) { cerr << "Could not get ICAP_YRESOLUTION" << endl; bret = false; } else { bret = pfCap->GetCurrent(fVal); settings->m_fYResolution = fVal; } if (0 == (pfRCap = dynamic_cast(findCapability(ICAP_CONTRAST)))) { cerr << "Could not get ICAP_CONTRAST" << endl; bret = false; } else { bret = pfRCap->GetCurrent(fVal); settings->m_fContrast = fVal; } if (0 == (pfRCap = dynamic_cast(findCapability(ICAP_BRIGHTNESS)))) { cerr << "Could not get ICAP_BRIGHTNESS" << endl; bret = false; } else { bret = pfRCap->GetCurrent(fVal); settings->m_fBrightness = fVal; } // Y resolution the same. if (0 == (pfRCap = dynamic_cast(findCapability(ICAP_GAMMA)))) { cerr << "Could not get ICAP_GAMMA" << endl; bret = false; } else { bret = pfRCap->GetCurrent(fVal); settings->m_fGamma = fVal; } if (0 == (pbCap = dynamic_cast(findCapability(ICAP_AUTOMATICCROPUSESFRAME)))) { cerr << "Could not get ICAP_AUTOMATICCROPUSESFRAME" << endl; bret = false; } else { bret = pbCap->GetCurrent(bVal); settings->m_bAutoCrop = bVal; } //填充黑框 if (0 == (pbCap = dynamic_cast(findCapability(0x8004)))) { cerr << "Could not get ICAP_AUTOMATICCROPUSESFRAME" << endl; bret = false; } else { bret = pbCap->GetCurrent(bVal); settings->m_bFillBlackRect = bVal; } if (0 == (pbCap = dynamic_cast(findCapability(ICAP_AUTODISCARDBLANKPAGES)))) { cerr << "Could not get ICAP_AUTODISCARDBLANKPAGES" << endl; bret = false; } else { bret = pbCap->GetCurrent(bVal); settings->m_bAutoDiscardBlank = bVal; } if (0 == (pbCap = dynamic_cast(findCapability(0x8091)))) { cerr << "Could not get ICAP_AUTODISCARDBLANKPAGES" << endl; bret = false; } else { bret = pbCap->GetCurrent(bVal); settings->m_bAutoDiscardBlankInvoice = bVal; } if (0 == (pbCap = dynamic_cast(findCapability(ICAP_AUTOMATICDESKEW)))) { cerr << "Could not get ICAP_AUTOMATICDESKEW" << endl; bret = false; } else { bret = pbCap->GetCurrent(bVal); settings->m_bAutoDeskew = bVal; } if (0 == (pbCap = dynamic_cast(findCapability(CAP_DOUBLEFEEDDETECTION)))) { cerr << "Could not get CAP_DOUBLEFEEDDETECTION" << endl; bret = false; } else { bret = pbCap->GetCurrent(bVal); settings->m_HardWareParams.DoubleFeederOn = bVal; } if (0 == (pbCap = dynamic_cast(findCapability(0x8005))))//背面旋转180 { cerr << "Could not get CAP_SKREWDETECT" << endl; bret = false; } else { bret = pbCap->GetCurrent(bVal); settings->m_bBackRotate180 = bVal; } #ifdef G200 if (0 == (pbCap = dynamic_cast(findCapability(0x8006))))//歪斜检测 { cerr << "Could not get CAP_SKREWDETECT" << endl; bret = false; } else { bret = pbCap->GetCurrent(bVal); settings->m_HardWareParams.SkrewDetectOn = bVal; } if (0 == (pfRCap = dynamic_cast(findCapability(0x8021))))//歪斜检测等级 { cerr << "Could not get CAP_SKREWDETECTLEVEL" << endl; bret = false; } else { bret = pfRCap->GetCurrent(fVal); settings->m_HardWareParams.SkrewDetectLevel = fVal; } if (0 == (pbCap = dynamic_cast(findCapability(0x8090))))//装订检测 { cerr << "Could not get CAP_STAPLEDETECT" << endl; bret = false; } else { bret = pbCap->GetCurrent(bVal); settings->m_HardWareParams.StapleDetectOn = bVal; } #endif // G200 if (0 == (pnCap = dynamic_cast(findCapability(CAP_XFERCOUNT)))) { //XdPrint("updateScannerFromCaps CAP_XFERCOUNT Error"); } else { bret = pnCap->GetCurrent(nVal); m_Xfers.Count = nVal; bool bVal = settings->m_bDuplex; if (bVal){ if (nVal % 2 == 1) nVal += 1; } //settings->m_wScanCount = 0; nVal == -1 ? settings->m_wScanCount = -1:(settings->m_wScanCount = (bVal ? nVal / 2 : nVal)); //XdPrint("updateScannerFromCaps CAP_XFERCOUNT :%d \n", settings->m_wScanCount); } //去除穿孔 if (0 == (pbCap = dynamic_cast(findCapability(0x8018)))) { bret = false; } else { bret = pbCap->GetCurrent(bVal); settings->m_OutHole.EnOutHole = bVal; if (bVal) { settings->m_bDuplex = true; } } //去除穿孔占幅面比例 if (0 == (pfRCap = dynamic_cast(findCapability(0x8092)))) { bret = false; } else { pfRCap->GetCurrent(fVal); settings->m_OutHole.OutHoleRatio = (int)fVal; } //多流除红 if (0 == (pbCap = dynamic_cast(findCapability(0x8026)))) { bret = false; } else { bret = pbCap->GetCurrent(bVal); settings->m_bMultiOutput = bVal; } return bret; } ////////////////////////////////////////////////////////////////////////////// bool CTWAINDS_FreeImage::DoCloseDSOkEvent() { if (dsState_Enabled != m_CurrentState) { setConditionCode(TWCC_SEQERROR); return false; } // Update the scanner with the latest negotiated caps //if (!updateScannerFromCaps()) //{ // return false; //} return CTWAINDS_Base::DoCloseDSOkEvent(); } ////////////////////////////////////////////////////////////////////////////// CTWAINContainer* CTWAINDS_FreeImage::findCapability(const TW_UINT16 _unCap) { CTWAINContainer* pRet = 0; // When adding to findCapabiltiy remember the order of operations // Some capabilities are dependent on others. // see: http://www.twain.org/docs/CapOrderForWeb.PDF switch (_unCap) { case ICAP_FRAMES: pRet = m_pICAP_FRAMES; break; case ICAP_BITDEPTH: pRet = getICAP_BITDEPTH(); break; case CAP_DEVICEONLINE: { CTWAINContainerBool* pBoolCon = dynamic_cast(m_IndependantCapMap[CAP_DEVICEONLINE]); if (NULL != pBoolCon) { pBoolCon->SetCurrent(m_Scanner.getDeviceOnline() ? TRUE : FALSE); pRet = pBoolCon; } } break; case CUSTCAP_DOCS_IN_ADF: { CTWAINContainerInt* pIntCon = dynamic_cast(m_IndependantCapMap[CUSTCAP_DOCS_IN_ADF]); if (NULL != pIntCon) { pIntCon->SetCurrent(m_Scanner.GetMaxPagesInADF()); pRet = pIntCon; } } break; case CAP_FEEDERLOADED: { CTWAINContainerBool* pBoolCon = dynamic_cast(m_IndependantCapMap[CAP_FEEDERLOADED]); if (NULL != pBoolCon) { pBoolCon->SetCurrent(m_Scanner.isFeederLoaded() ? TRUE : FALSE); pRet = pBoolCon; } } break; case CAP_SERIALNUMBER: { CTWAINContainerString* pStringCon = dynamic_cast(m_IndependantCapMap[CAP_SERIALNUMBER]); if (NULL != pStringCon) { pStringCon->SetCurrent(m_Scanner.getSerialNum()); pRet = pStringCon; } } break; case 0x8025://FWVersion { CTWAINContainerString* pStringCon = dynamic_cast(m_IndependantCapMap[0x8025]); if (NULL != pStringCon) { pStringCon->SetCurrent(m_Scanner.getFWVersion()); pRet = pStringCon; } } break; default: // cycle through m_IndependantCapMap pRet = CTWAINDS_Base::findCapability(_unCap); break; } return pRet; } ////////////////////////////////////////////////////////////////////////////// CTWAINContainer* CTWAINDS_FreeImage::getICAP_BITDEPTH() { CTWAINContainer* pRet = 0; // BitDepth depends on PixelType TWAINCapabilitiesMap::iterator itCap = m_IndependantCapMap.find(ICAP_PIXELTYPE); if (itCap != m_IndependantCapMap.end()) { int nCurrentVal = -1; CTWAINContainerInt* pnCap = dynamic_cast(itCap->second); if ((0 != pnCap) && (pnCap->GetCurrent(nCurrentVal))) { TWAINCapabilitiesMap_int::iterator itBDCap = m_BitDepthMap.find(nCurrentVal); if (itBDCap != m_BitDepthMap.end()) { pRet = itBDCap->second; } } } return pRet; } ////////////////////////////////////////////////////////////////////////////// TW_INT16 CTWAINDS_FreeImage::dat_imagelayout(TW_UINT16 _MSG, pTW_IMAGELAYOUT _pData) { TW_INT16 twrc = TWRC_SUCCESS; switch (_MSG) { case MSG_GET: case MSG_GETCURRENT: case MSG_GETDEFAULT: if (!(dsState_Open == m_CurrentState || dsState_Enabled == m_CurrentState || dsState_XferReady == m_CurrentState)) { setConditionCode(TWCC_SEQERROR); return TWRC_FAILURE; } break; case MSG_RESET: case MSG_SET: if (dsState_Open != m_CurrentState) { setConditionCode(TWCC_SEQERROR); return TWRC_FAILURE; } break; } if ((0 == _pData) || (0 == m_pICAP_FRAMES)) { setConditionCode(TWCC_BADVALUE); return TWRC_FAILURE; } CTWAINContainerInt* pDepCap = dynamic_cast(findCapability(ICAP_SUPPORTEDSIZES)); switch (_MSG) { case MSG_RESET: if (!pDepCap->Reset()) { setConditionCode(TWCC_CAPBADOPERATION); twrc = TWRC_FAILURE; } else { // this will update the frame to match the papersize updatePostDependencies(MSG_RESET, ICAP_SUPPORTEDSIZES); } //change the behavior to a get current _MSG = MSG_GETCURRENT; case MSG_GET: case MSG_GETCURRENT: case MSG_GETDEFAULT: { InternalFrame frame; if (MSG_GETDEFAULT == _MSG) { if (!m_pICAP_FRAMES->GetDefault(frame)) { twrc = TWRC_FAILURE; setConditionCode(TWCC_CAPBADOPERATION); } } else { if (!m_pICAP_FRAMES->GetCurrent(frame)) { twrc = TWRC_FAILURE; setConditionCode(TWCC_CAPBADOPERATION); } } if (TWRC_SUCCESS == twrc) { int unit = TWUN_PIXELS; float Xres = 100; float Yres = 100; getCurrentUnits(unit, Xres, Yres); _pData->Frame = frame.AsTW_FRAME(unit, Xres, Yres); _pData->FrameNumber = m_pICAP_FRAMES->getIndexForValue(frame); _pData->DocumentNumber = m_DocumentNumber; _pData->PageNumber = m_PageNumber; } } break; case MSG_SET: { /// @todo check frame with physical extents. If frame is too big or too small modify it /// and return TWCC_BADVALUE if too big else TWRC_CHECKSTATUS if changed. // Application that want multiple frames should negotiated frames through ICAP_FRAMES // Layout can only set the current frame. // Our simple source only supports one frame. TW_CAPABILITY cap; TW_HANDLE hContainer = _DSM_Alloc(sizeof(TW_ONEVALUE_FRAME)); if (0 != hContainer) { cap.hContainer = hContainer; cap.Cap = ICAP_FRAMES; cap.ConType = TWON_ONEVALUE; pTW_ONEVALUE_FRAME pCap = (pTW_ONEVALUE_FRAME)_DSM_LockMemory(cap.hContainer); pCap->Item = _pData->Frame; int unit = TWUN_PIXELS; float Xres = 100; float Yres = 100; twrc = getCurrentUnits(unit, Xres, Yres); InternalFrame frame(pCap->Item, unit, Xres, Yres); bool bConstrained; if (!ConstrainFrameToScanner(frame, bConstrained)) { setConditionCode(TWCC_BADVALUE); twrc = TWRC_FAILURE; } else if (bConstrained) { pCap->Item = frame.AsTW_FRAME(unit, Xres, Yres); twrc = TWRC_CHECKSTATUS; } pCap->ItemType = TWTY_FRAME; _DSM_UnlockMemory(hContainer); TW_INT16 Condition; if (m_pICAP_FRAMES->Set(&cap, Condition)) { updatePostDependencies(MSG_SET, ICAP_FRAMES); } _DSM_Free(hContainer); } else { twrc = TWRC_FAILURE; setConditionCode(TWCC_CAPBADOPERATION); } if (_pData->DocumentNumber != TWON_DONTCARE32) { m_DocumentNumber = _pData->DocumentNumber; } if (_pData->PageNumber != TWON_DONTCARE32) { m_PageNumber = _pData->PageNumber; } } break; default: setConditionCode(TWCC_BADPROTOCOL); assert(0); twrc = TWRC_FAILURE; break; } return twrc; } TW_INT16 CTWAINDS_FreeImage::dat_extimageinfo(TW_UINT16 _MSG, pTW_EXTIMAGEINFO _pData) { //TW_INFO info; //info.InfoID=TWEI_BOOKNAME; //info.ItemType=TWTY_UINT32; //uint aa=22; //info.Item=&aa; //info.ReturnCode=TWRC_SUCCESS; //_pData->Info->NumItems=1; //_pData->Info-> //_pData->Info=info; //return TWRC_SUCCESS; setConditionCode(TWCC_CAPUNSUPPORTED); return TWRC_SUCCESS; } ////////////////////////////////////////////////////////////////////////////// TW_INT16 CTWAINDS_FreeImage::GetGustomDSData(pTW_CUSTOMDSDATA _pDSData) { stringstream DsData; if (_pDSData == 0) { setConditionCode(TWCC_BADVALUE); return TWRC_FAILURE; } if (StoreCustomDSdata(DsData)) { DsData.seekp(0, ios_base::end); DWORD dwSize = (DWORD)DsData.tellp(); _pDSData->InfoLength = dwSize + sizeof(TW_GUID); TW_HANDLE hData = _DSM_Alloc(_pDSData->InfoLength); if (hData == 0) { setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } char* pData = (char*)_DSM_LockMemory(hData); if (pData == 0) { _DSM_Free(hData); setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } memcpy(pData, &CustomDSGUI, sizeof(TW_GUID)); pData += sizeof(TW_GUID); DsData.seekg(0, ios_base::beg); DsData.read(pData, dwSize); _DSM_UnlockMemory(hData); _pDSData->hData = hData; return TWRC_SUCCESS; } setConditionCode(TWCC_BUMMER); return TWRC_FAILURE; } ////////////////////////////////////////////////////////////////////////////// TW_INT16 CTWAINDS_FreeImage::SetGustomDSData(pTW_CUSTOMDSDATA _pDSData) { if (_pDSData == 0 || _pDSData->hData == 0 || _pDSData->InfoLength <= sizeof(TW_GUID)) { setConditionCode(TWCC_BADVALUE); return TWRC_FAILURE; } stringstream DsData; char* pData = (char*)_DSM_LockMemory(_pDSData->hData); if (pData == 0) { setConditionCode(TWCC_LOWMEMORY); return TWRC_FAILURE; } if (memcmp(pData, &CustomDSGUI, sizeof(TW_GUID)) == 0) { pData += sizeof(TW_GUID); DsData.write(pData, _pDSData->InfoLength); _DSM_UnlockMemory(_pDSData->hData); stringstream DsDataBackUp; if (StoreCustomDSdata(DsDataBackUp))//Back up current settings { if (ReadCustomDSdata(DsData)) { return TWRC_SUCCESS; } ReadCustomDSdata(DsDataBackUp);//restore current settings } } setConditionCode(TWCC_BADVALUE); return TWRC_FAILURE; } ////////////////////////////////////////////////////////////////////////////// TW_INT16 CTWAINDS_FreeImage::validateCapabilitySet(TW_UINT16 _Cap, TW_UINT16 _ConType, BYTE* _pContainer) { TW_INT16 twrc = CTWAINDS_Base::validateCapabilitySet(_Cap, _ConType, _pContainer); if (twrc != TWRC_SUCCESS) { return twrc; } switch (_Cap) { case CUSTCAP_DOCS_IN_ADF: { twrc = TWRC_FAILURE; if (TWON_ONEVALUE == _ConType) { pTW_ONEVALUE pCap = (pTW_ONEVALUE)_pContainer; if (pCap) { if ((TW_INT16)pCap->Item >= 0) { twrc = TWRC_SUCCESS; m_Scanner.SetMaxPagesInADF((TW_INT16)pCap->Item); } } } break; } default: break; } return twrc; } bool CTWAINDS_FreeImage::StartScanning(bool showUI) { while (!m_Scanner.isPaperOn()) { std::string text = StringToUtf("检测到无纸,请添加纸张"); std::string op = StringToUtf("提示"); if (MessageBoxA(NULL,text.c_str(), op.c_str(), MB_YESNO | MB_SYSTEMMODAL) == IDNO) return false(); } // Update the scanner with the latest negotiated caps if (!updateScannerFromCaps()) { //XdPrint("Update updateScannerFromCaps() Error"); setConditionCode(TWCC_BADVALUE); return false; } if (bIndicators) { m_pGUI->UpdateProgress(true, '0', 0, "0"); //indi.ShowWindow(SW_SHOWNORMAL); } bool ret = m_Scanner.acquireImage(); if (bIndicators) { if (!ret) { m_pGUI->UpdateProgress(false, '0', 0, "0"); } } return ret; }; bool CTWAINDS_FreeImage::StopScanning() { m_bCanceled = true; return m_Scanner.StopScan(); }