2619 lines
69 KiB
C++
2619 lines
69 KiB
C++
/***************************************************************************
|
||
* 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_Base.cpp
|
||
* Base class describing a TWAIN Data Source.
|
||
* @author TWAIN Working Group
|
||
* @date April 2007
|
||
*/
|
||
#include "stdafx.h"
|
||
#include "CTWAINDS_Base.h"
|
||
#include "filetools.h"
|
||
#include <Windows.h>
|
||
#if (TWNDS_CMP == TWNDS_CMP_VISUALCPP)
|
||
#include <io.h>
|
||
#endif
|
||
|
||
#ifdef TWNDS_OS_APPLE
|
||
#import <QuickTime/QuickTime.h> // for GraphicsImporter
|
||
#endif
|
||
|
||
#include <fcntl.h>
|
||
#include <sys/stat.h>
|
||
#include <sstream>
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
CTWAINDS_Base::CTWAINDS_Base() :
|
||
m_DSConditionCode(TWCC_SUCCESS)
|
||
{
|
||
memset(&m_MyIdentity, 0, sizeof(m_MyIdentity));
|
||
memset(&m_App, 0, sizeof(m_App));
|
||
m_CurrentState = dsState_Loaded;
|
||
memset(&m_CurFileExferName, 0, sizeof(m_CurFileExferName));
|
||
memset(&m_DefFileExferName, 0, sizeof(m_DefFileExferName));
|
||
memset(&m_Xfers, 0, sizeof(m_Xfers));
|
||
m_nDestScanLine = 0;
|
||
m_hImageData = 0;
|
||
m_DocumentNumber = 0;
|
||
m_PageNumber = 0;
|
||
return;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
CTWAINDS_Base::~CTWAINDS_Base()
|
||
{
|
||
memset(&m_MyIdentity, 0, sizeof(TW_IDENTITY));
|
||
memset(&m_App, 0, sizeof(TW_IDENTITY));
|
||
|
||
// free all resources belonging to m_IndependantCapMap
|
||
TWAINCapabilitiesMap::iterator cur = m_IndependantCapMap.begin();
|
||
|
||
while(cur != m_IndependantCapMap.end())
|
||
{
|
||
delete cur->second;
|
||
cur++;
|
||
}
|
||
|
||
if(m_hImageData)
|
||
{
|
||
_DSM_Free(m_hImageData);
|
||
m_hImageData = 0;
|
||
}
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
void CTWAINDS_Base::fillIdentityStructure(TW_IDENTITY& _idStruct)
|
||
{
|
||
// fill in the Identity structure
|
||
SSTRNCPY(_idStruct.Manufacturer, sizeof(_idStruct.Manufacturer), "Unknown", 32);
|
||
SSTRNCPY(_idStruct.ProductFamily, sizeof(_idStruct.ProductFamily), "Unknown", 32);
|
||
SSTRNCPY(_idStruct.ProductName, sizeof(_idStruct.ProductName), "Unknown", 32);
|
||
}
|
||
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_UINT16 CTWAINDS_Base::DS_Entry( pTW_IDENTITY _pOrigin,
|
||
TW_UINT32 _DG,
|
||
TW_UINT16 _DAT,
|
||
TW_UINT16 _MSG,
|
||
TW_MEMREF _pData)
|
||
{
|
||
TW_INT16 twrc = TWRC_SUCCESS;
|
||
|
||
//string ss;
|
||
switch (_DG)
|
||
{
|
||
|
||
case DG_CONTROL:
|
||
{
|
||
//ss="DG_CONTROL";
|
||
switch (_DAT)
|
||
{
|
||
case DAT_EVENT:
|
||
{
|
||
//ss+=" DAT_EVENT";
|
||
twrc = dat_event(_MSG, (pTW_EVENT) _pData);
|
||
}
|
||
break;
|
||
|
||
case DAT_IDENTITY:
|
||
{
|
||
//ss+=" DAT_IDENTITY";
|
||
twrc = dat_identity(_pOrigin, _MSG, (pTW_IDENTITY) _pData);
|
||
}
|
||
break;
|
||
|
||
case DAT_CAPABILITY:
|
||
//ss+=" DAT_CAPABILITY";
|
||
twrc = dat_capability(_MSG, (pTW_CAPABILITY) _pData);
|
||
break;
|
||
|
||
case DAT_USERINTERFACE:
|
||
{
|
||
//ss+=" DAT_USERINTERFACE";
|
||
twrc = dat_userinterface(_MSG, (pTW_USERINTERFACE) _pData);
|
||
}
|
||
break;
|
||
|
||
case DAT_SETUPFILEXFER:
|
||
//ss+=" DAT_SETUPFILEXFER";
|
||
twrc = dat_setupfilexfer(_MSG, (pTW_SETUPFILEXFER) _pData);
|
||
break;
|
||
|
||
case DAT_SETUPMEMXFER:
|
||
{
|
||
//ss+=" DAT_SETUPMEMXFER";
|
||
twrc = dat_setupmemxfer(_MSG, (pTW_SETUPMEMXFER) _pData);
|
||
}
|
||
break;
|
||
|
||
case DAT_STATUS:
|
||
{
|
||
//ss+=" DAT_STATUS";
|
||
twrc = dat_status(_MSG, (pTW_STATUS) _pData);
|
||
}
|
||
break;
|
||
|
||
case DAT_PENDINGXFERS:
|
||
//ss+=" DAT_PENDINGXFERS";
|
||
twrc = dat_pendingxfers(_MSG, (pTW_PENDINGXFERS)_pData);
|
||
break;
|
||
|
||
case DAT_ENTRYPOINT:
|
||
//ss+=" DAT_ENTRYPOINT";
|
||
twrc = dat_entrypoint(_MSG, (pTW_ENTRYPOINT)_pData);
|
||
break;
|
||
|
||
case DAT_XFERGROUP:
|
||
//ss="DAT_XFERGROUP";
|
||
twrc = dat_xfergroup(_MSG, (pTW_UINT32)_pData);
|
||
break;
|
||
|
||
case DAT_CUSTOMDSDATA:
|
||
//ss+=" DAT_CUSTOMDSDATA";
|
||
twrc = dat_customdsdata(_MSG, (pTW_CUSTOMDSDATA)_pData);
|
||
break;
|
||
|
||
default:
|
||
//ss="setConditionCode(TWCC_BADPROTOCOL)";
|
||
setConditionCode(TWCC_BADPROTOCOL);
|
||
//assert(0);
|
||
twrc = TWRC_FAILURE;
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case DG_IMAGE:
|
||
{
|
||
// ss="DG_IMAGE ";
|
||
switch (_DAT)
|
||
{
|
||
case DAT_IMAGEINFO:
|
||
//ss+="DAT_IMAGEINFO";
|
||
twrc = dat_imageinfo(_MSG, (pTW_IMAGEINFO)_pData);
|
||
break;
|
||
|
||
case DAT_IMAGENATIVEXFER:
|
||
if(0 == _pData)
|
||
{
|
||
//ss+="DAT_IMAGENATIVEXFER Error";
|
||
setConditionCode(TWCC_BADVALUE);
|
||
return TWRC_FAILURE;
|
||
}
|
||
//ss+="DAT_IMAGENATIVEXFER";
|
||
twrc = dat_imagenativexfer(_MSG, *((TW_HANDLE*)_pData));
|
||
break;
|
||
|
||
case DAT_IMAGEFILEXFER:
|
||
//ss+="DAT_IMAGEFILEXFER";
|
||
twrc = dat_imagefilexfer(_MSG);
|
||
break;
|
||
|
||
case DAT_IMAGEMEMXFER:
|
||
//ss+="DAT_IMAGEMEMXFER";
|
||
twrc = dat_imagememxfer(_MSG, (pTW_IMAGEMEMXFER)_pData);
|
||
break;
|
||
|
||
case DAT_IMAGELAYOUT:
|
||
//ss+="DAT_IMAGELAYOUT";
|
||
twrc = dat_imagelayout(_MSG, (pTW_IMAGELAYOUT)_pData);
|
||
break;
|
||
|
||
case DAT_EXTIMAGEINFO:
|
||
//ss+="DAT_EXTIMAGEINFO";
|
||
twrc = dat_extimageinfo(_MSG, (pTW_EXTIMAGEINFO)_pData);
|
||
break;
|
||
|
||
default:
|
||
//ss+="default setConditionCode(TWCC_CAPUNSUPPORTED)";
|
||
setConditionCode(TWCC_CAPUNSUPPORTED);
|
||
//assert(0);
|
||
twrc = TWRC_FAILURE;
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
|
||
default:
|
||
//ss+="default setConditionCode(TWCC_CAPUNSUPPORTED)";
|
||
setConditionCode(TWCC_CAPUNSUPPORTED);
|
||
//assert(0);
|
||
twrc = TWRC_FAILURE;
|
||
break;
|
||
}
|
||
//ss+=twrc==TWRC_FAILURE?" TWRC_FAILURE":" TWRC_SUCCESS";
|
||
//FileTools::write_log("D:/1.txt",ss);
|
||
return twrc;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::dat_event(TW_UINT16 _MSG,
|
||
pTW_EVENT _pEvent)
|
||
{
|
||
TW_INT16 twrc = TWRC_SUCCESS;
|
||
|
||
if (_pEvent==0)
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
twrc = TWRC_FAILURE;
|
||
}
|
||
|
||
else
|
||
{
|
||
switch(_MSG)
|
||
{
|
||
case MSG_PROCESSEVENT:
|
||
twrc = processEvent(_pEvent);
|
||
break;
|
||
|
||
default:
|
||
setConditionCode(TWCC_BADPROTOCOL);
|
||
//assert(0);
|
||
twrc = TWRC_FAILURE;
|
||
break;
|
||
}
|
||
}
|
||
|
||
return twrc;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::dat_identity(pTW_IDENTITY _pOrigin,
|
||
TW_UINT16 _MSG,
|
||
pTW_IDENTITY _pData)
|
||
{
|
||
TW_INT16 twrc = TWRC_SUCCESS;
|
||
//string ss="dat_identity ";
|
||
switch(_MSG)
|
||
{
|
||
case MSG_GET:
|
||
//ss+="MSG_GET";
|
||
memcpy(_pData, &m_MyIdentity, sizeof(TW_IDENTITY));
|
||
break;
|
||
|
||
case MSG_OPENDS:
|
||
// store the id assigned to us by the DSM.
|
||
//ss+="MSG_OPENDS ";
|
||
m_MyIdentity.Id = _pData->Id;
|
||
twrc = openDS(_pOrigin);
|
||
break;
|
||
|
||
case MSG_CLOSEDS:
|
||
//ss+="MSG_CLOSEDS ";
|
||
twrc = closeDS();
|
||
break;
|
||
|
||
default:
|
||
setConditionCode(TWCC_BADPROTOCOL);
|
||
//assert(0);
|
||
twrc = TWRC_FAILURE;
|
||
break;
|
||
}
|
||
//ss+=twrc==TWRC_SUCCESS?"TWRC_SUCCESS":"TWRC_FAILURE";
|
||
//FileTools::write_log("D:/1.txt",ss);
|
||
return twrc;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::dat_capability(TW_UINT16 _MSG,
|
||
pTW_CAPABILITY _pCap)
|
||
{
|
||
|
||
TW_INT16 twrc = TWRC_FAILURE;
|
||
|
||
if(MSG_RESETALL == _MSG) // special case
|
||
{
|
||
// Reject anything state 5 or higher...
|
||
if(m_CurrentState >= dsState_Enabled)
|
||
{
|
||
setConditionCode(TWCC_SEQERROR);
|
||
//FileTools::write_log("D:/1.txt","dat_capability m_CurrentState >= dsState_Enabled");
|
||
return TWRC_FAILURE;
|
||
}
|
||
// Loop through all supported caps and reset them.
|
||
CTWAINContainer *pCap = NULL;
|
||
CTWAINContainerInt *pCapSC = dynamic_cast<CTWAINContainerInt*>(findCapability(CAP_SUPPORTEDCAPS));
|
||
if(!pCapSC)
|
||
{
|
||
//FileTools::write_log("D:/1.txt","dat_capability !pCapSC");
|
||
setConditionCode(TWCC_BADCAP);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
/*int value = pCapSC->getIndexForValue(ICAP_SUPPORTEDSIZES);*/
|
||
|
||
const IntVector listInts = pCapSC->GetSupported();
|
||
|
||
twrc = TWRC_SUCCESS;
|
||
const int nSize = (int)(listInts.size());
|
||
int x;
|
||
for(x = 0; x < nSize; ++x)
|
||
{
|
||
int Cap = listInts[x];
|
||
if(NULL != (pCap = findCapability(Cap)))
|
||
{
|
||
if(pCap->isOperationAllowed(MSG_RESET))
|
||
{
|
||
if(!pCap->Reset())
|
||
{
|
||
//ostringstream os;
|
||
//os<<pCap->GetCapID();
|
||
//istringstream is(os.str());
|
||
//string out;
|
||
//is>>out;
|
||
//FileTools::write_log("D:/1.txt","dat_capability !pCap->Reset())"+out);
|
||
setConditionCode(TWCC_CAPUNSUPPORTED);
|
||
twrc = TWRC_FAILURE;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// check for invalid args
|
||
if(0 == _pCap)
|
||
{
|
||
//FileTools::write_log("D:/1.txt","0 == _pCap");
|
||
setConditionCode(TWCC_BADVALUE);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
// first find the capability
|
||
CTWAINContainer* pCap = findCapability(_pCap->Cap);
|
||
|
||
// Now handle the cap if one was found
|
||
if(0 != pCap)
|
||
{
|
||
twrc = handleCap(_MSG, pCap, _pCap);
|
||
if (twrc!=TWRC_SUCCESS)
|
||
{
|
||
//ostringstream os;
|
||
//os<<pCap->GetCapID();
|
||
//istringstream is(os.str());
|
||
//string out;
|
||
//is>>out;
|
||
//ostringstream osc;
|
||
//osc<<_MSG;
|
||
//istringstream isc(osc.str());
|
||
//string sc;
|
||
//isc>> sc;
|
||
|
||
//ostringstream osrc;
|
||
//osrc<<twrc;
|
||
//istringstream isrc(osrc.str());
|
||
//string src;
|
||
//isrc>> src;
|
||
//FileTools::write_log("D:/1.txt","handleCap "+out+"MSG "+sc +"TWRC "+src );
|
||
}
|
||
|
||
// when some capabilities are successfully changed with Set or Reset
|
||
// it requires changing others
|
||
if( (twrc == TWRC_SUCCESS || twrc == TWRC_CHECKSTATUS) &&
|
||
(MSG_SET == _MSG || MSG_RESET == _MSG) )
|
||
{
|
||
TW_INT16 twrc2 = updatePostDependencies(_MSG, _pCap->Cap);
|
||
//if (twrc2!=TWRC_SUCCESS)
|
||
//{
|
||
//ostringstream os;
|
||
//os<<pCap->GetCapID();
|
||
//istringstream is(os.str());
|
||
//string out;
|
||
//is>>out;
|
||
//FileTools::write_log("D:/1.txt","handleCap 1 "+out);
|
||
//}
|
||
if(twrc == TWRC_SUCCESS && twrc2 != TWRC_SUCCESS)
|
||
{
|
||
twrc = twrc2;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return twrc;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
CTWAINContainer* CTWAINDS_Base::findCapability(const TW_UINT16 _unCap)
|
||
{
|
||
CTWAINContainer* pCap = 0;
|
||
|
||
TWAINCapabilitiesMap::iterator itCap = m_IndependantCapMap.find(_unCap);
|
||
|
||
if(itCap == m_IndependantCapMap.end())
|
||
{
|
||
setConditionCode(TWCC_CAPUNSUPPORTED);
|
||
}
|
||
else
|
||
{
|
||
pCap = itCap->second;
|
||
}
|
||
|
||
return pCap;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::dat_userinterface(TW_UINT16 _MSG,
|
||
pTW_USERINTERFACE _pData)
|
||
{
|
||
TW_INT16 twrc = TWRC_SUCCESS;
|
||
|
||
if (_pData==0)
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
//assert(0);
|
||
twrc = TWRC_FAILURE;
|
||
}
|
||
|
||
else
|
||
{
|
||
switch(_MSG)
|
||
{
|
||
case MSG_ENABLEDS:
|
||
twrc = enableDS(_pData);
|
||
break;
|
||
|
||
case MSG_ENABLEDSUIONLY:
|
||
twrc = enableDSOnly(_pData);
|
||
break;
|
||
|
||
case MSG_DISABLEDS:
|
||
twrc = disableDS(_pData);
|
||
break;
|
||
|
||
default:
|
||
setConditionCode(TWCC_BADPROTOCOL);
|
||
//assert(0);
|
||
twrc = TWRC_FAILURE;
|
||
break;
|
||
}
|
||
}
|
||
|
||
return twrc;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::dat_setupfilexfer( TW_UINT16 _MSG,
|
||
pTW_SETUPFILEXFER _pData)
|
||
{
|
||
TW_INT16 twrc = TWRC_SUCCESS;
|
||
//FileTools::write_log("D:/1.txt","dat_setupfilexfer");
|
||
switch(_MSG)
|
||
{
|
||
case MSG_GET:
|
||
twrc = getFileXfer(_pData);
|
||
break;
|
||
|
||
case MSG_GETDEFAULT:
|
||
twrc = getDefaultFileXfer(_pData);
|
||
break;
|
||
|
||
case MSG_RESET:
|
||
twrc = resetFileXfer(_pData);
|
||
break;
|
||
|
||
case MSG_SET:
|
||
twrc = setFileXfer(_pData);
|
||
break;
|
||
|
||
default:
|
||
setConditionCode(TWCC_BADPROTOCOL);
|
||
//assert(0);
|
||
twrc = TWRC_FAILURE;
|
||
break;
|
||
}
|
||
|
||
return twrc;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::dat_setupmemxfer(TW_UINT16 _MSG,
|
||
pTW_SETUPMEMXFER _pData)
|
||
{
|
||
TW_INT16 twrc = TWRC_SUCCESS;
|
||
//FileTools::write_log("D:/1.txt","getMemoryXfer");
|
||
switch(_MSG)
|
||
{
|
||
case MSG_GET:
|
||
twrc = getMemoryXfer(_pData);
|
||
break;
|
||
|
||
default:
|
||
setConditionCode(TWCC_BADPROTOCOL);
|
||
//assert(0);
|
||
twrc = TWRC_FAILURE;
|
||
break;
|
||
}
|
||
|
||
return twrc;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::dat_imagenativexfer(TW_UINT16 _MSG,
|
||
TW_HANDLE& _hData)
|
||
{
|
||
TW_INT16 twrc = TWRC_SUCCESS;
|
||
|
||
switch(_MSG)
|
||
{
|
||
case MSG_GET:
|
||
twrc = transferNativeImage(_hData);
|
||
break;
|
||
|
||
default:
|
||
setConditionCode(TWCC_BADPROTOCOL);
|
||
//assert(0);
|
||
twrc = TWRC_FAILURE;
|
||
break;
|
||
}
|
||
|
||
return twrc;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::dat_imagefilexfer(TW_UINT16 _MSG)
|
||
{
|
||
TW_INT16 twrc = TWRC_SUCCESS;
|
||
|
||
switch(_MSG)
|
||
{
|
||
case MSG_GET:
|
||
twrc = saveImageFile();
|
||
break;
|
||
|
||
default:
|
||
setConditionCode(TWCC_BADPROTOCOL);
|
||
//assert(0);
|
||
twrc = TWRC_FAILURE;
|
||
break;
|
||
}
|
||
|
||
return twrc;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::dat_customdsdata(TW_UINT16 _MSG, pTW_CUSTOMDSDATA _pDSData)
|
||
{
|
||
TW_INT16 twrc = TWRC_SUCCESS;
|
||
if(m_CurrentState != dsState_Open)
|
||
{
|
||
setConditionCode(TWCC_SEQERROR);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
switch(_MSG)
|
||
{
|
||
case MSG_GET:
|
||
twrc = GetGustomDSData(_pDSData);
|
||
break;
|
||
|
||
case MSG_SET:
|
||
twrc = SetGustomDSData(_pDSData);
|
||
break;
|
||
|
||
default:
|
||
setConditionCode(TWCC_BADPROTOCOL);
|
||
//assert(0);
|
||
twrc = TWRC_FAILURE;
|
||
break;
|
||
}
|
||
|
||
return twrc;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::dat_imagememxfer(TW_UINT16 _MSG,
|
||
pTW_IMAGEMEMXFER _pData)
|
||
{
|
||
TW_INT16 twrc = TWRC_SUCCESS;
|
||
|
||
switch(_MSG)
|
||
{
|
||
case MSG_GET:
|
||
twrc = transferMemoryBuffers(_pData);
|
||
break;
|
||
|
||
default:
|
||
setConditionCode(TWCC_BADPROTOCOL);
|
||
//assert(0);
|
||
twrc = TWRC_FAILURE;
|
||
break;
|
||
}
|
||
|
||
return twrc;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::dat_imagelayout(TW_UINT16,
|
||
pTW_IMAGELAYOUT)
|
||
{
|
||
// This should be implemented in the derived class.
|
||
setConditionCode(TWCC_CAPUNSUPPORTED);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::dat_extimageinfo(TW_UINT16,
|
||
pTW_EXTIMAGEINFO)
|
||
{
|
||
//pTW_EXTIMAGEINFO->Info[0].
|
||
// This should be implemented in the derived class.
|
||
setConditionCode(TWCC_CAPUNSUPPORTED);
|
||
return TWRC_FAILURE;
|
||
//return TWRC_SUCCESS;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::getConditionCode() const
|
||
{
|
||
return m_DSConditionCode;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
void CTWAINDS_Base::setConditionCode(TW_INT16 _cc)
|
||
{
|
||
m_DSConditionCode = _cc;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
pTW_IDENTITY CTWAINDS_Base::getIdentity()
|
||
{
|
||
return &m_MyIdentity;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::dat_imageinfo(TW_UINT16 _MSG,
|
||
pTW_IMAGEINFO _pImageInfo)
|
||
{
|
||
TW_INT16 twrc = TWRC_SUCCESS;
|
||
|
||
switch(_MSG)
|
||
{
|
||
case MSG_GET:
|
||
twrc = getImageInfo(_pImageInfo);
|
||
break;
|
||
|
||
default:
|
||
setConditionCode(TWCC_BADPROTOCOL);
|
||
//assert(0);
|
||
twrc = TWRC_FAILURE;
|
||
break;
|
||
}
|
||
|
||
return twrc;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::dat_status(TW_UINT16 _MSG,
|
||
pTW_STATUS _pStatus)
|
||
{
|
||
TW_INT16 twrc = TWRC_SUCCESS;
|
||
|
||
if (_pStatus==0)
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
twrc = TWRC_FAILURE;
|
||
}
|
||
|
||
else
|
||
{
|
||
switch(_MSG)
|
||
{
|
||
case MSG_GET:
|
||
_pStatus->ConditionCode = getConditionCode();
|
||
setConditionCode(TWCC_SUCCESS);
|
||
break;
|
||
|
||
default:
|
||
setConditionCode(TWCC_BADPROTOCOL);
|
||
//assert(0);
|
||
twrc = TWRC_FAILURE;
|
||
break;
|
||
}
|
||
}
|
||
|
||
return twrc;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::dat_pendingxfers(TW_UINT16 _MSG,
|
||
pTW_PENDINGXFERS _pXfers)
|
||
{
|
||
TW_INT16 twrc = TWRC_SUCCESS;
|
||
|
||
switch(_MSG)
|
||
{
|
||
case MSG_ENDXFER:
|
||
//FileTools::write_log("D:/1.txt","dat_pendingxfers endxfer");
|
||
twrc = endXfer(_pXfers);
|
||
break;
|
||
|
||
case MSG_GET:
|
||
//FileTools::write_log("D:/1.txt","dat_pendingxfers getXfer");
|
||
twrc = getXfer(_pXfers);
|
||
break;
|
||
|
||
case MSG_RESET:
|
||
//FileTools::write_log("D:/1.txt","dat_pendingxfers resetXfer");
|
||
twrc = resetXfer(_pXfers);
|
||
break;
|
||
|
||
default:
|
||
setConditionCode(TWCC_BADPROTOCOL);
|
||
//assert(0);
|
||
twrc = TWRC_FAILURE;
|
||
break;
|
||
}
|
||
|
||
return twrc;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::dat_entrypoint(TW_UINT16 _MSG,
|
||
pTW_ENTRYPOINT _pEntryPoints)
|
||
{
|
||
TW_INT16 twrc = TWRC_SUCCESS;
|
||
|
||
switch(_MSG)
|
||
{
|
||
case MSG_SET:
|
||
setEntryPoints(_pEntryPoints);
|
||
twrc = TWRC_SUCCESS;
|
||
break;
|
||
|
||
default:
|
||
setConditionCode(TWCC_BADPROTOCOL);
|
||
//assert(0);
|
||
twrc = TWRC_FAILURE;
|
||
break;
|
||
}
|
||
|
||
return twrc;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::dat_xfergroup(TW_UINT16 _MSG,
|
||
pTW_UINT32 _pXferGroup)
|
||
{
|
||
TW_INT16 twrc = TWRC_SUCCESS;
|
||
|
||
if(!_pXferGroup)
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
switch(_MSG)
|
||
{
|
||
case MSG_GET:
|
||
*_pXferGroup = DG_IMAGE;
|
||
twrc = TWRC_SUCCESS;
|
||
break;
|
||
|
||
case MSG_SET:
|
||
if(*_pXferGroup != DG_IMAGE)
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
return TWRC_FAILURE;
|
||
}
|
||
twrc = TWRC_SUCCESS;
|
||
break;
|
||
|
||
default:
|
||
setConditionCode(TWCC_BADPROTOCOL);
|
||
//assert(0);
|
||
twrc = TWRC_FAILURE;
|
||
break;
|
||
}
|
||
|
||
return twrc;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
bool CTWAINDS_Base::DoXferReadyEvent()
|
||
{
|
||
bool bRC = false;
|
||
|
||
if( dsState_Enabled != m_CurrentState )
|
||
{
|
||
setConditionCode(TWCC_SEQERROR);
|
||
return bRC;
|
||
}
|
||
|
||
/// @TODO check to see if we are simplex or duplex.
|
||
/// Document only updates with new sheet of paper.
|
||
m_DocumentNumber++;
|
||
m_PageNumber++;
|
||
m_CurrentState = dsState_XferReady;
|
||
getImageInfo(&m_ImageInfo);
|
||
|
||
#ifdef TWNDS_OS_APPLE
|
||
TW_CALLBACK callback = {};
|
||
callback.Message = MSG_XFERREADY;
|
||
|
||
bRC = TWRC_SUCCESS==_DSM_Entry(getIdentity(),
|
||
(pTW_IDENTITY)NULL,
|
||
(TW_UINT32)DG_CONTROL,
|
||
(TW_UINT16)DAT_CALLBACK,
|
||
(TW_UINT16)MSG_INVOKE_CALLBACK,
|
||
(TW_MEMREF) &callback);
|
||
#else
|
||
// Tell the DSM that we are ready to send images
|
||
if(TWRC_SUCCESS==_DSM_Entry(getIdentity(),
|
||
getApp(),
|
||
DG_CONTROL,
|
||
DAT_NULL,
|
||
MSG_XFERREADY,
|
||
0))
|
||
{
|
||
bRC = true;
|
||
}
|
||
#endif
|
||
return bRC;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
bool CTWAINDS_Base::DoCloseDSRequestEvent()
|
||
{
|
||
bool bRC = false;
|
||
|
||
if( dsState_Enabled != m_CurrentState )
|
||
{
|
||
setConditionCode(TWCC_SEQERROR);
|
||
return bRC;
|
||
}
|
||
#ifdef TWNDS_OS_APPLE
|
||
TW_CALLBACK callback = {};
|
||
callback.Message = MSG_CLOSEDSREQ;
|
||
|
||
bRC = TWRC_SUCCESS==_DSM_Entry(getIdentity(),
|
||
(pTW_IDENTITY)NULL,
|
||
(TW_UINT32)DG_CONTROL,
|
||
(TW_UINT16)DAT_CALLBACK,
|
||
(TW_UINT16)MSG_INVOKE_CALLBACK,
|
||
(TW_MEMREF) &callback);
|
||
#else
|
||
// Tell the DSM that DS request to close or disable our user interface
|
||
// most likly user clicks on the <20>CLOSE?button on GUI
|
||
if(TWRC_SUCCESS==_DSM_Entry(getIdentity(),
|
||
getApp(),
|
||
DG_CONTROL,
|
||
DAT_NULL,
|
||
MSG_CLOSEDSREQ,
|
||
0))
|
||
{
|
||
bRC = true;
|
||
}
|
||
#endif
|
||
return bRC;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
bool CTWAINDS_Base::DoCloseDSOkEvent()
|
||
{
|
||
bool bRC = false;
|
||
|
||
if( dsState_Enabled != m_CurrentState )
|
||
{
|
||
setConditionCode(TWCC_SEQERROR);
|
||
return bRC;
|
||
}
|
||
|
||
#ifdef TWNDS_OS_APPLE
|
||
TW_CALLBACK callback = {};
|
||
callback.Message = MSG_CLOSEDSOK;
|
||
|
||
bRC = TWRC_SUCCESS==_DSM_Entry(getIdentity(),
|
||
(pTW_IDENTITY)NULL,
|
||
(TW_UINT32)DG_CONTROL,
|
||
(TW_UINT16)DAT_CALLBACK,
|
||
(TW_UINT16)MSG_INVOKE_CALLBACK,
|
||
(TW_MEMREF) &callback);
|
||
#else
|
||
// Tell the DSM that we are ready to send images
|
||
// most likly user clicks on the <20>OK?button on GUI
|
||
if(TWRC_SUCCESS==_DSM_Entry(getIdentity(),
|
||
getApp(),
|
||
DG_CONTROL,
|
||
DAT_NULL,
|
||
MSG_CLOSEDSOK,
|
||
0))
|
||
{
|
||
bRC = true;
|
||
//FileTools::write_log("D:/1.txt"," DoCloseDSOkEvent");
|
||
}
|
||
#endif
|
||
return bRC;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
bool CTWAINDS_Base::DoDeviceEvent()
|
||
{
|
||
//Report to the DSM that a device event has occurred
|
||
bool bRC = false;
|
||
return bRC;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
pTW_IDENTITY CTWAINDS_Base::getApp()
|
||
{
|
||
return &m_App;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
template<class TWAINContainerType>
|
||
TW_INT16 CTWAINDS_Base::handleCap(TW_UINT16 _MSG, TWAINContainerType* _pContainer, pTW_CAPABILITY _pCap)
|
||
{
|
||
TW_INT16 twrc = TWRC_FAILURE;
|
||
|
||
if(MSG_QUERYSUPPORT == _MSG) // special case
|
||
{
|
||
_pCap->ConType = TWON_ONEVALUE;
|
||
_pCap->hContainer = _DSM_Alloc(sizeof(TW_ONEVALUE));
|
||
|
||
if(0 != _pCap->hContainer)
|
||
{
|
||
pTW_ONEVALUE pCap = (pTW_ONEVALUE)_DSM_LockMemory(_pCap->hContainer);
|
||
|
||
pCap->ItemType = TWTY_INT32;
|
||
pCap->Item = _pContainer->getMSG_QUERYSUPPORT();
|
||
|
||
_DSM_UnlockMemory(_pCap->hContainer);
|
||
twrc = TWRC_SUCCESS;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// first check if the operation is allowed on this container
|
||
if(!_pContainer->isOperationAllowed(_MSG))
|
||
{
|
||
//FileTools::write_log("D:/1.txt","handleCap !_pContainer->isOperationAllowed(_MSG)");
|
||
setConditionCode(TWCC_CAPBADOPERATION);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
switch(_pContainer->GetItemType())
|
||
{
|
||
case TWTY_INT8:
|
||
case TWTY_INT16:
|
||
case TWTY_INT32:
|
||
case TWTY_UINT8:
|
||
case TWTY_UINT16:
|
||
case TWTY_BOOL:
|
||
case TWTY_FIX32:
|
||
case TWTY_FRAME:
|
||
case TWTY_STR32:
|
||
case TWTY_STR64:
|
||
case TWTY_STR128:
|
||
case TWTY_STR255:
|
||
twrc = TWRC_SUCCESS; // so far so good
|
||
break;
|
||
|
||
default:
|
||
setConditionCode(TWCC_CAPBADOPERATION);
|
||
return TWRC_FAILURE;
|
||
break;
|
||
|
||
} // switch(_pContainer->GetGetType())
|
||
|
||
if(TWRC_SUCCESS == twrc)
|
||
{
|
||
// Now that the type is valid, do the actual operation
|
||
switch(_MSG)
|
||
{
|
||
case MSG_RESET:
|
||
//MSG_RESET is supposed to reset and then return the current value
|
||
if(m_CurrentState >= dsState_Enabled)
|
||
{
|
||
//FileTools::write_log("D:/1.txt"," handleCap m_CurrentState >= dsState_Enabled");
|
||
setConditionCode(TWCC_SEQERROR);
|
||
twrc = TWRC_FAILURE;
|
||
break;
|
||
}
|
||
_pContainer->Reset();
|
||
//change the behavior to a get current
|
||
_MSG = MSG_GETCURRENT;
|
||
case MSG_GETCURRENT:
|
||
case MSG_GETDEFAULT:
|
||
case MSG_GET:
|
||
_pCap->ConType = _pContainer->GetGetType(_MSG);
|
||
twrc = updatePreDependencies(_pContainer);
|
||
if(twrc != TWRC_SUCCESS)
|
||
{
|
||
//FileTools::write_log("D:/1.txt"," handleCap twrc != TWRC_SUCCESS");
|
||
break;
|
||
}
|
||
|
||
_pCap->hContainer = _pContainer->GetContainer(_MSG);
|
||
twrc = updatePostContainer(_pCap);
|
||
if (twrc!=TWRC_SUCCESS)
|
||
{
|
||
//FileTools::write_log("D:/1.txt"," handleCap twrc != TWRC_SUCCESS 2");
|
||
}
|
||
break;
|
||
|
||
case MSG_SET:
|
||
{
|
||
if(m_CurrentState >= dsState_Enabled)
|
||
{
|
||
//FileTools::write_log("D:/1.txt"," handleCap MSG_SET m_CurrentState >= dsState_Enabled");
|
||
setConditionCode(TWCC_SEQERROR);
|
||
twrc = TWRC_FAILURE;
|
||
break;
|
||
}
|
||
twrc = updatePreDependencies(_pContainer);
|
||
if(twrc != TWRC_SUCCESS)
|
||
{
|
||
//FileTools::write_log("D:/1.txt"," handleCap MSG_SET twrc != TWRC_SUCCESS 3");
|
||
break;
|
||
}
|
||
twrc = updatePreContainer(_pCap);
|
||
if(twrc!=TWRC_SUCCESS)
|
||
{
|
||
//FileTools::write_log("D:/1.txt"," handleCap MSG_SET twrc != TWRC_SUCCESS 4");
|
||
break;
|
||
}
|
||
BYTE * pContainer = (BYTE*)_DSM_LockMemory(_pCap->hContainer);
|
||
if(pContainer==0)
|
||
{
|
||
setConditionCode(TWCC_LOWMEMORY);
|
||
//FileTools::write_log("D:/1.txt"," pContainer==0 512");
|
||
twrc = TWRC_FAILURE;
|
||
break;
|
||
}
|
||
twrc = validateCapabilitySet(_pCap->Cap,_pCap->ConType, pContainer);
|
||
//if (twrc!=TWRC_SUCCESS)
|
||
//{
|
||
// FileTools::write_log("D:/1.txt"," pContainer==0 1024");
|
||
//}
|
||
_DSM_UnlockMemory(_pCap->hContainer);
|
||
if(twrc != TWRC_SUCCESS)
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
// if(twrc == TWRC_FAILURE)
|
||
// {
|
||
//FileTools::write_log("D:/1.txt"," handleCap MSG_SET twrc = validateCapabilitySet(_pCap->Cap,_pCap->ConType, pContainer);");
|
||
// break;
|
||
// }
|
||
}
|
||
|
||
TW_INT16 Condition;
|
||
TW_INT16 twrc2 = _pContainer->Set(_pCap, Condition);
|
||
if(twrc2 != TWRC_SUCCESS)
|
||
{
|
||
setConditionCode(Condition);
|
||
if(twrc == TWRC_SUCCESS && twrc2 != TWRC_SUCCESS)
|
||
{
|
||
//FileTools::write_log("D:/1.txt"," handleCap MSG_SET TW_INT16 twrc2 = _pContainer->Set(_pCap, Condition);");
|
||
twrc = twrc2;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
default:
|
||
setConditionCode(TWCC_CAPBADOPERATION);
|
||
break;
|
||
}
|
||
} // if(TWRC_SUCCESS == twrc)
|
||
}
|
||
|
||
return twrc;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::validateCapabilitySet(TW_UINT16 _Cap, TW_UINT16 _ConType, BYTE* _pContainer)
|
||
{
|
||
TW_INT16 twrc = TWRC_SUCCESS;
|
||
|
||
switch(_Cap)
|
||
{
|
||
case CAP_XFERCOUNT:
|
||
{
|
||
twrc = TWRC_FAILURE;
|
||
if(TWON_ONEVALUE == _ConType)
|
||
{
|
||
pTW_ONEVALUE pCap = (pTW_ONEVALUE)_pContainer;
|
||
|
||
if(pCap)
|
||
{
|
||
if( (TW_INT16)pCap->Item == -1 || (TW_INT16)pCap->Item > 0 )
|
||
{
|
||
twrc = TWRC_SUCCESS;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case ICAP_GAMMA:
|
||
{
|
||
twrc = TWRC_FAILURE;
|
||
if(TWON_ONEVALUE == _ConType)
|
||
{
|
||
pTW_ONEVALUE_FIX32 pCap = (pTW_ONEVALUE_FIX32)_pContainer;
|
||
if(pCap)
|
||
{
|
||
float flVal = FIX32ToFloat(pCap->Item);
|
||
if( flVal>0 )
|
||
{
|
||
twrc = TWRC_SUCCESS;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case ICAP_FRAMES:
|
||
{
|
||
int unit = TWUN_PIXELS;
|
||
float Xres = 100;
|
||
float Yres = 100;
|
||
twrc = getCurrentUnits(unit, Xres, Yres);
|
||
|
||
if(TWON_ONEVALUE == _ConType)
|
||
{
|
||
pTW_ONEVALUE_FRAME pCap = (pTW_ONEVALUE_FRAME)_pContainer;
|
||
|
||
if(pCap && pCap->ItemType == TWTY_FRAME)
|
||
{
|
||
InternalFrame frame(pCap->Item, unit, Xres, Yres);
|
||
bool bConstrained;
|
||
if(!ConstrainFrameToScanner(frame,bConstrained))
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
//FileTools::write_log("D:/1.txt","uvalidateCapabilitySet 6");
|
||
twrc = TWRC_FAILURE;
|
||
}
|
||
else if(bConstrained)
|
||
{
|
||
pCap->Item = frame.AsTW_FRAME(unit, Xres, Yres);
|
||
twrc = TWRC_CHECKSTATUS;
|
||
}
|
||
}
|
||
}
|
||
else if(TWON_ENUMERATION == _ConType)
|
||
{
|
||
CTWAINContainerInt *pDepCapMax = dynamic_cast<CTWAINContainerInt*>(findCapability(ICAP_MAXFRAMES));
|
||
if(pDepCapMax==0)
|
||
{
|
||
setConditionCode(TWCC_BUMMER);
|
||
//FileTools::write_log("D:/1.txt","uvalidateCapabilitySet 7");
|
||
twrc = TWRC_FAILURE;
|
||
}
|
||
else
|
||
{
|
||
pTW_ENUMERATION_FRAME pCap = (pTW_ENUMERATION_FRAME)_pContainer;
|
||
int nMax;
|
||
if(!pDepCapMax->GetCurrent(nMax) || pCap->NumItems>(TW_UINT32)nMax)
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
//FileTools::write_log("D:/1.txt","uvalidateCapabilitySet 8");
|
||
twrc = TWRC_FAILURE;
|
||
}
|
||
else
|
||
{
|
||
if(pCap && pCap->ItemType == TWTY_FRAME)
|
||
{
|
||
for(TW_UINT32 x = 0; x < pCap->NumItems; ++x)
|
||
{
|
||
InternalFrame frame(pCap->ItemList[x], unit, Xres, Yres);
|
||
bool bConstrained;
|
||
if(!ConstrainFrameToScanner(frame,bConstrained))
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
//FileTools::write_log("D:/1.txt","uvalidateCapabilitySet 9");
|
||
twrc = TWRC_FAILURE;
|
||
}
|
||
else if(bConstrained)
|
||
{
|
||
pCap->ItemList[x] = frame.AsTW_FRAME(unit, Xres, Yres);
|
||
//FileTools::write_log("D:/1.txt","uvalidateCapabilitySet 10");
|
||
twrc = TWRC_CHECKSTATUS;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case ICAP_MAXFRAMES:
|
||
if(TWON_ONEVALUE == _ConType)
|
||
{
|
||
TW_ONEVALUE *pCap = (TW_ONEVALUE*)_pContainer;
|
||
|
||
if(!pCap || pCap->ItemType != TWTY_UINT16 || pCap->Item!=1)
|
||
{
|
||
//FileTools::write_log("D:/1.txt","uvalidateCapabilitySet 11");
|
||
twrc = TWRC_FAILURE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//FileTools::write_log("D:/1.txt","uvalidateCapabilitySet 12");
|
||
setConditionCode(TWCC_CAPBADOPERATION);
|
||
twrc = TWRC_FAILURE;
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
return twrc;
|
||
}
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::updatePreContainer(pTW_CAPABILITY _pCap)
|
||
{
|
||
TW_INT16 twrc = TWRC_SUCCESS;
|
||
BYTE * pContainer = (BYTE*)_DSM_LockMemory(_pCap->hContainer);
|
||
if(pContainer==0)
|
||
{
|
||
//FileTools::write_log("D:/1.txt","updatePreContainer(pTW_CAPABILITY _pCap) 12");
|
||
setConditionCode(TWCC_LOWMEMORY);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
switch(_pCap->Cap)
|
||
{
|
||
case ICAP_XRESOLUTION:
|
||
case ICAP_YRESOLUTION:
|
||
{
|
||
int nUnit = TWUN_INCHES;
|
||
CTWAINContainerInt *pnCap = 0;
|
||
if( 0 == (pnCap = dynamic_cast<CTWAINContainerInt*>(findCapability(ICAP_UNITS)))
|
||
|| false == pnCap->GetCurrent(nUnit))
|
||
{
|
||
//FileTools::write_log("D:/1.txt","updatePreContainer(pTW_CAPABILITY _pCap) 6");
|
||
setConditionCode(TWCC_OPERATIONERROR);
|
||
twrc = TWRC_FAILURE;
|
||
}
|
||
else
|
||
{
|
||
if(nUnit==TWUN_PIXELS)
|
||
{
|
||
//FileTools::write_log("D:/1.txt","updatePreContainer(pTW_CAPABILITY _pCap) 5");
|
||
setConditionCode(TWCC_CAPSEQERROR);
|
||
twrc = TWRC_FAILURE;
|
||
}
|
||
else
|
||
{
|
||
if(TWON_ONEVALUE == _pCap->ConType)
|
||
{
|
||
pTW_ONEVALUE_FIX32 pCap = (pTW_ONEVALUE_FIX32)pContainer;
|
||
|
||
if(pCap==0 || pCap->ItemType != TWTY_FIX32)
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
//FileTools::write_log("D:/1.txt","updatePreContainer(pTW_CAPABILITY _pCap) 7");
|
||
twrc = TWRC_FAILURE;
|
||
}
|
||
else
|
||
{
|
||
pCap->Item = ConvertUnits(pCap->Item,TWUN_PIXELS,nUnit,1.0);
|
||
}
|
||
}
|
||
else if(TWON_ENUMERATION == _pCap->ConType)
|
||
{
|
||
pTW_ENUMERATION_FIX32 pCap = (pTW_ENUMERATION_FIX32)pContainer;
|
||
if(pCap==0 || pCap->ItemType != TWTY_FIX32)
|
||
{
|
||
//FileTools::write_log("D:/1.txt","updatePreContainer(pTW_CAPABILITY _pCap) 0");
|
||
setConditionCode(TWCC_BADVALUE);
|
||
twrc = TWRC_FAILURE;
|
||
}
|
||
else
|
||
{
|
||
for(TW_UINT32 x = 0; x < pCap->NumItems; ++x)
|
||
{
|
||
pCap->ItemList[x] = ConvertUnits(pCap->ItemList[x],TWUN_PIXELS,nUnit,1.0);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
_DSM_UnlockMemory(_pCap->hContainer);
|
||
|
||
return twrc;
|
||
}
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::updatePostContainer(pTW_CAPABILITY _pCap)
|
||
{
|
||
TW_INT16 twrc = TWRC_SUCCESS;
|
||
BYTE * pContainer = (BYTE*)_DSM_LockMemory(_pCap->hContainer);
|
||
if(pContainer==0)
|
||
{
|
||
setConditionCode(TWCC_LOWMEMORY);
|
||
//FileTools::write_log("D:/1.txt","updatePostContainer(pTW_CAPABILITY _pCap) 0");
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
switch(_pCap->Cap)
|
||
{
|
||
case ICAP_XRESOLUTION:
|
||
case ICAP_YRESOLUTION:
|
||
{
|
||
int nUnit = TWUN_PIXELS;
|
||
float Xres = 100;
|
||
float Yres = 100;
|
||
twrc = getCurrentUnits(nUnit, Xres, Yres);
|
||
if(_pCap->Cap==ICAP_YRESOLUTION)
|
||
{
|
||
Xres = Yres;
|
||
}
|
||
if(twrc==TWRC_SUCCESS)
|
||
{
|
||
if(TWON_ONEVALUE == _pCap->ConType)
|
||
{
|
||
pTW_ONEVALUE_FIX32 pCap = (pTW_ONEVALUE_FIX32)pContainer;
|
||
|
||
if(pCap==0 || pCap->ItemType != TWTY_FIX32)
|
||
{
|
||
//FileTools::write_log("D:/1.txt","updatePostContainer(pTW_CAPABILITY _pCap) 1");
|
||
setConditionCode(TWCC_BADVALUE);
|
||
twrc = TWRC_FAILURE;
|
||
}
|
||
else
|
||
{
|
||
pCap->Item = ConvertUnits(pCap->Item,nUnit,TWUN_INCHES,Xres);
|
||
}
|
||
}
|
||
else if(TWON_ENUMERATION == _pCap->ConType)
|
||
{
|
||
pTW_ENUMERATION_FIX32 pCap = (pTW_ENUMERATION_FIX32)pContainer;
|
||
if(pCap==0 || pCap->ItemType != TWTY_FIX32)
|
||
{
|
||
//FileTools::write_log("D:/1.txt","updatePostContainer(pTW_CAPABILITY _pCap) 2");
|
||
setConditionCode(TWCC_BADVALUE);
|
||
twrc = TWRC_FAILURE;
|
||
}
|
||
else
|
||
{
|
||
for(TW_UINT32 x = 0; x < pCap->NumItems; ++x)
|
||
{
|
||
pCap->ItemList[x] = ConvertUnits(pCap->ItemList[x],nUnit, TWUN_PIXELS,Xres);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case ICAP_PHYSICALHEIGHT:
|
||
case ICAP_PHYSICALWIDTH:
|
||
{
|
||
int nUnit = TWUN_PIXELS;
|
||
float Xres = 100;
|
||
float Yres = 100;
|
||
twrc = getCurrentUnits(nUnit, Xres, Yres);
|
||
if(_pCap->Cap==ICAP_PHYSICALHEIGHT)
|
||
{
|
||
Xres = Yres;
|
||
}
|
||
if(twrc==TWRC_SUCCESS)
|
||
{
|
||
if(TWON_ONEVALUE == _pCap->ConType)
|
||
{
|
||
pTW_ONEVALUE_FIX32 pCap = (pTW_ONEVALUE_FIX32)pContainer;
|
||
|
||
if(pCap==0 || pCap->ItemType != TWTY_FIX32)
|
||
{
|
||
//FileTools::write_log("D:/1.txt","updatePostContainer(pTW_CAPABILITY _pCap) 3");
|
||
setConditionCode(TWCC_BADVALUE);
|
||
twrc = TWRC_FAILURE;
|
||
}
|
||
else
|
||
{
|
||
pCap->Item = ConvertUnits(pCap->Item,TWUN_PIXELS,nUnit,Xres);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
setConditionCode(TWCC_OPERATIONERROR);
|
||
//FileTools::write_log("D:/1.txt","updatePostContainer(pTW_CAPABILITY _pCap) 4");
|
||
twrc = TWRC_FAILURE;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
_DSM_UnlockMemory(_pCap->hContainer);
|
||
|
||
return twrc;
|
||
}
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::updatePreDependencies(CTWAINContainer* _pContainer)
|
||
{
|
||
TW_INT16 twrc = TWRC_SUCCESS;
|
||
|
||
switch(_pContainer->GetCapID())
|
||
{
|
||
case ICAP_FRAMES:
|
||
{
|
||
int unit = TWUN_PIXELS;
|
||
float Xres = 100;
|
||
float Yres = 100;
|
||
twrc = getCurrentUnits(unit, Xres, Yres);
|
||
CTWAINContainerFrame *pnCap = dynamic_cast<CTWAINContainerFrame*>(_pContainer);
|
||
if(pnCap)
|
||
{
|
||
pnCap->setCurrentUnits(unit, Xres, Yres);
|
||
}
|
||
else
|
||
{
|
||
//FileTools::write_log("D:/1.txt","(CTWAINContainer* _pContainer) 1");
|
||
twrc = TWRC_FAILURE;
|
||
}
|
||
}
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
|
||
return twrc;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::updatePostDependencies(TW_UINT16 MSG, TW_UINT16 Cap)
|
||
{
|
||
TW_INT16 twrc = TWRC_SUCCESS;
|
||
|
||
// Handle some special post dependancy cases
|
||
// This is where capabilities that depend on the one that just got changed
|
||
// must also get changed so they stay in sync.
|
||
|
||
// Check to see what got changed
|
||
switch(Cap)
|
||
{
|
||
case ICAP_SUPPORTEDSIZES:
|
||
{
|
||
// if ICAP_SUPPORTEDSIZES was modified, ICAP_FRAME needs to be synced.
|
||
CTWAINContainerInt *pDepCapSS = dynamic_cast<CTWAINContainerInt*>(findCapability(ICAP_SUPPORTEDSIZES));
|
||
CTWAINContainerFrame *pDepCapFrames = dynamic_cast<CTWAINContainerFrame*>(findCapability(ICAP_FRAMES));
|
||
|
||
if(0 == pDepCapSS || 0 == pDepCapFrames)
|
||
{
|
||
setConditionCode(TWCC_CAPBADOPERATION);
|
||
//FileTools::write_log("D:/1.txt","updatePostDependencies 0");
|
||
twrc = TWRC_FAILURE;
|
||
break;
|
||
}
|
||
|
||
if( MSG == MSG_SET
|
||
|| MSG == MSG_RESET )
|
||
{
|
||
int ss;
|
||
pDepCapSS->GetCurrent(ss);
|
||
InternalFrame frame(ss);
|
||
bool bConstrained;
|
||
ConstrainFrameToScanner(frame,bConstrained);
|
||
pDepCapFrames->Set(frame);
|
||
}
|
||
}
|
||
break;
|
||
|
||
case ICAP_FRAMES:
|
||
{
|
||
// if ICAP_FRAMES was modified, ICAP_SUPPORTEDSIZES needs to be synced.
|
||
CTWAINContainerInt *pDepCapSS = dynamic_cast<CTWAINContainerInt*>(findCapability(ICAP_SUPPORTEDSIZES));
|
||
CTWAINContainerFrame *pDepCapFrames = dynamic_cast<CTWAINContainerFrame*>(findCapability(ICAP_FRAMES));
|
||
|
||
if(0 == pDepCapSS || 0 == pDepCapFrames)
|
||
{
|
||
setConditionCode(TWCC_CAPBADOPERATION);
|
||
//FileTools::write_log("D:/1.txt","updatePostDependencies 1");
|
||
twrc = TWRC_FAILURE;
|
||
break;
|
||
}
|
||
|
||
if( MSG == MSG_SET
|
||
|| MSG == MSG_RESET )
|
||
{
|
||
// Figure out if the current frame is in our list of ICAP_SUPPORTEDSIZES
|
||
// if it is in the list, then we need to set the current SS to match
|
||
// loop through all of our Supported Sizes and make a frame from them
|
||
// then see if the frame matches the one we have.
|
||
|
||
InternalFrame curFrame;
|
||
pDepCapFrames->GetCurrent(curFrame);
|
||
const IntVector listInts = pDepCapSS->GetSupported();
|
||
|
||
const int nSize = (int)(listInts.size());
|
||
int x;
|
||
for(x = 0; x < nSize; ++x)
|
||
{
|
||
int ss = listInts[x];
|
||
InternalFrame frame(ss);
|
||
if(curFrame == frame)
|
||
{
|
||
pDepCapSS->SetCurrent(ss);
|
||
break;
|
||
}
|
||
}
|
||
|
||
// No match found
|
||
if(x >= nSize)
|
||
{
|
||
if(!pDepCapSS->SetCurrent(TWSS_NONE))
|
||
{
|
||
pDepCapSS->Add(TWSS_NONE);
|
||
pDepCapSS->SetCurrent(TWSS_NONE);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case ICAP_XRESOLUTION:
|
||
case ICAP_YRESOLUTION:
|
||
case ICAP_UNITS:
|
||
{
|
||
int unit;
|
||
float Xres, Yres;
|
||
CTWAINContainerFrame *pDepCapFrames = dynamic_cast<CTWAINContainerFrame*>(findCapability(ICAP_FRAMES));
|
||
|
||
if(pDepCapFrames ==0)
|
||
{
|
||
setConditionCode(TWCC_BUMMER);
|
||
//FileTools::write_log("D:/1.txt","updatePostDependencies 3");
|
||
twrc = TWRC_FAILURE;
|
||
break;
|
||
}
|
||
|
||
if(getCurrentUnits(unit, Xres, Yres)==TWRC_SUCCESS)
|
||
{
|
||
pDepCapFrames->setCurrentUnits(unit, Xres, Yres);
|
||
}
|
||
else
|
||
{
|
||
setConditionCode(TWCC_BUMMER);
|
||
//FileTools::write_log("D:/1.txt","updatePostDependencies 4");
|
||
return TWRC_FAILURE;
|
||
}
|
||
}
|
||
break;
|
||
case CAP_FEEDERENABLED:
|
||
//TODO add routine here if CAP_DUPLEXENABLED supports TRUE
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
return twrc;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
bool CTWAINDS_Base::ConstrainFrameToScanner(InternalFrame& _frame, bool &bConstrained)
|
||
{
|
||
bConstrained = false;
|
||
int nMaxHValue = 0x7FFFFFFF; //max frame size fit in InternalFrame
|
||
int nMinHValue = 0;
|
||
int nMaxWValue = 0x7FFFFFFF; //max frame size fit in InternalFrame
|
||
int nMinWValue = 0;
|
||
float fTemp;
|
||
// ICAP_PHYSICALWIDTH and ICAP_PHYSICALHEIGHT are required Caps while
|
||
// ICAP_MINIMUMWIDTH and ICAP_MINIMUMHEIGHT are not required caps.
|
||
CTWAINContainerFix32* pPhysicalWidth = dynamic_cast<CTWAINContainerFix32*>(findCapability(ICAP_PHYSICALWIDTH));
|
||
CTWAINContainerFix32* pPhysicalHeight = dynamic_cast<CTWAINContainerFix32*>(findCapability(ICAP_PHYSICALHEIGHT));
|
||
CTWAINContainerFix32* pMinWidth = dynamic_cast<CTWAINContainerFix32*>(findCapability(ICAP_MINIMUMWIDTH));
|
||
CTWAINContainerFix32* pMinHeight = dynamic_cast<CTWAINContainerFix32*>(findCapability(ICAP_MINIMUMHEIGHT));
|
||
|
||
if(pPhysicalWidth)
|
||
{
|
||
if(pPhysicalWidth->GetCurrent(fTemp))
|
||
{
|
||
nMaxWValue = (int)(fTemp*1000.0);
|
||
}
|
||
}
|
||
if(pPhysicalHeight)
|
||
{
|
||
if(pPhysicalHeight->GetCurrent(fTemp))
|
||
{
|
||
nMaxHValue = (int)(fTemp*1000.0);
|
||
}
|
||
}
|
||
if(pMinWidth)
|
||
{
|
||
if(pMinWidth->GetCurrent(fTemp))
|
||
{
|
||
nMinWValue = (int)(fTemp*1000.0);
|
||
}
|
||
}
|
||
if(pMinHeight)
|
||
{
|
||
if(pMinHeight->GetCurrent(fTemp))
|
||
{
|
||
nMinHValue = (int)(fTemp*1000.0);
|
||
}
|
||
}
|
||
|
||
// Constrain the width
|
||
if(_frame.nLeft < 0)
|
||
{
|
||
/*
|
||
_frame.nLeft = 0;
|
||
bConstrained = true;
|
||
*/
|
||
return false;
|
||
}
|
||
if(_frame.nRight <= 0 || _frame.nRight > nMaxWValue)
|
||
{
|
||
/*
|
||
_frame.nRight = nMaxWValue;
|
||
bConstrained = true;
|
||
*/
|
||
return false;
|
||
}
|
||
if(_frame.nLeft >= _frame.nRight)
|
||
{
|
||
_frame.nLeft = 0;
|
||
_frame.nRight = nMaxWValue;
|
||
bConstrained = true;
|
||
}
|
||
|
||
if((_frame.nRight-_frame.nLeft) < nMinWValue)
|
||
{
|
||
_frame.nLeft = max( 0, _frame.nLeft - (nMinWValue - (_frame.nRight-_frame.nLeft)) );
|
||
_frame.nRight = _frame.nLeft + max(nMinWValue, _frame.nRight-_frame.nLeft);
|
||
bConstrained = true;
|
||
}
|
||
|
||
// Constrain the height
|
||
if(_frame.nTop < 0)
|
||
{
|
||
/*_frame.nTop = 0;
|
||
bConstrained = true;*/
|
||
return false;
|
||
}
|
||
if(_frame.nBottom <= 0 || _frame.nBottom>nMaxHValue)
|
||
{
|
||
/*
|
||
_frame.nBottom = nMaxHValue;
|
||
bConstrained = true;
|
||
*/
|
||
return false;
|
||
}
|
||
if(_frame.nTop >= _frame.nBottom)
|
||
{
|
||
_frame.nTop = 0;
|
||
_frame.nBottom = nMaxHValue;
|
||
bConstrained = true;
|
||
}
|
||
if(( _frame.nBottom-_frame.nTop)< nMinHValue)
|
||
{
|
||
_frame.nTop = max( 0, _frame.nTop - (nMinHValue - (_frame.nBottom-_frame.nTop)) );
|
||
_frame.nBottom = _frame.nTop + max(nMinHValue, _frame.nBottom-_frame.nTop);
|
||
bConstrained = true;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::getCurrentUnits(int &Unit, float &Xres, float &Yres)
|
||
{
|
||
TW_INT16 twrc = TWRC_SUCCESS;
|
||
CTWAINContainerFix32 *pfCap = 0;
|
||
CTWAINContainerInt *pnCap = 0;
|
||
|
||
// X resolution
|
||
if( 0 == (pfCap = dynamic_cast<CTWAINContainerFix32*>(findCapability(ICAP_XRESOLUTION)))
|
||
|| false == pfCap->GetCurrent(Xres) )
|
||
{
|
||
setConditionCode(TWCC_OPERATIONERROR);
|
||
twrc = TWRC_FAILURE;
|
||
}
|
||
|
||
// Y resolution
|
||
if( 0 == (pfCap = dynamic_cast<CTWAINContainerFix32*>(findCapability(ICAP_YRESOLUTION)))
|
||
|| false == pfCap->GetCurrent(Yres) )
|
||
{
|
||
setConditionCode(TWCC_OPERATIONERROR);
|
||
twrc = TWRC_FAILURE;
|
||
}
|
||
|
||
// Unit
|
||
if( 0 == (pnCap = dynamic_cast<CTWAINContainerInt*>(findCapability(ICAP_UNITS)))
|
||
|| false == pnCap->GetCurrent(Unit) )
|
||
{
|
||
setConditionCode(TWCC_OPERATIONERROR);
|
||
twrc = TWRC_FAILURE;
|
||
}
|
||
|
||
return twrc;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::getFileXfer(pTW_SETUPFILEXFER _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;
|
||
}
|
||
|
||
if(0 == _pData)
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
CTWAINContainerInt* pCap = dynamic_cast<CTWAINContainerInt*>(findCapability(ICAP_IMAGEFILEFORMAT));
|
||
if(0 == pCap)
|
||
{
|
||
setConditionCode(TWCC_BADPROTOCOL);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
SSTRCPY(_pData->FileName, sizeof(m_CurFileExferName), m_CurFileExferName);
|
||
int nCurFF;
|
||
pCap->GetCurrent(nCurFF);
|
||
_pData->Format = nCurFF;
|
||
|
||
return TWRC_SUCCESS;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::getDefaultFileXfer(pTW_SETUPFILEXFER _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;
|
||
}
|
||
|
||
if(0 == _pData)
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
CTWAINContainerInt* pCap = dynamic_cast<CTWAINContainerInt*>(findCapability(ICAP_IMAGEFILEFORMAT));
|
||
if(0 == pCap)
|
||
{
|
||
setConditionCode(TWCC_BADPROTOCOL);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
SSTRCPY(_pData->FileName, sizeof(m_DefFileExferName), m_DefFileExferName);
|
||
int nDefFF;
|
||
pCap->GetDefault(nDefFF);
|
||
_pData->Format = nDefFF;
|
||
|
||
return TWRC_SUCCESS;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::resetFileXfer(pTW_SETUPFILEXFER _pData)
|
||
{
|
||
// valid to call for 4 only
|
||
if( !(dsState_Open == m_CurrentState))
|
||
{
|
||
setConditionCode(TWCC_SEQERROR);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
if(0 == _pData)
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
CTWAINContainerInt* pCap = dynamic_cast<CTWAINContainerInt*>(findCapability(ICAP_IMAGEFILEFORMAT));
|
||
if(0 == pCap)
|
||
{
|
||
setConditionCode(TWCC_BADPROTOCOL);
|
||
return TWRC_FAILURE;
|
||
}
|
||
SSTRCPY(m_CurFileExferName, sizeof(m_CurFileExferName), m_DefFileExferName);
|
||
SSTRCPY(_pData->FileName, sizeof(m_CurFileExferName), m_CurFileExferName);
|
||
pCap->Reset();
|
||
int nCurFF = 0;
|
||
pCap->GetCurrent(nCurFF);
|
||
_pData->Format = nCurFF;
|
||
|
||
return TWRC_SUCCESS;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::setFileXfer(pTW_SETUPFILEXFER _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;
|
||
}
|
||
|
||
if(0 == _pData)
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
CTWAINContainerInt* pCap = dynamic_cast<CTWAINContainerInt*>(findCapability(ICAP_IMAGEFILEFORMAT));
|
||
if(0 == pCap)
|
||
{
|
||
setConditionCode(TWCC_BADPROTOCOL);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
if(!pCap->SetCurrent(_pData->Format))
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
return TWRC_CHECKSTATUS;
|
||
}
|
||
SSTRCPY(m_CurFileExferName, sizeof(m_CurFileExferName), _pData->FileName);
|
||
|
||
return TWRC_SUCCESS;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::saveImageFile()
|
||
{
|
||
TW_INT16 twrc = TWRC_FAILURE;
|
||
|
||
if( dsState_XferReady != m_CurrentState )
|
||
{
|
||
setConditionCode(TWCC_SEQERROR);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
// Get the image that should be waiting for us.
|
||
if(TWRC_SUCCESS != transfer())
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
int nCurFF = -1;
|
||
CTWAINContainerInt* pCap = dynamic_cast<CTWAINContainerInt*>(findCapability(ICAP_IMAGEFILEFORMAT));
|
||
if(0 == pCap || !pCap->GetCurrent(nCurFF))
|
||
{
|
||
setConditionCode(TWCC_BADPROTOCOL);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
// Do a quick test to see if we got a supported file type.
|
||
switch (nCurFF)
|
||
{
|
||
case TWFF_BMP:
|
||
twrc = saveImageFileAsBMP();
|
||
break;
|
||
|
||
case TWFF_TIFF:
|
||
twrc = saveImageFileAsTIFF();
|
||
break;
|
||
|
||
/*
|
||
Untill compression is implimented we support Jpeg
|
||
case TWFF_JFIF:
|
||
break;
|
||
*/
|
||
|
||
default:
|
||
setConditionCode(TWCC_BADVALUE);
|
||
return TWRC_FAILURE;
|
||
break;
|
||
}
|
||
|
||
if(twrc == TWRC_XFERDONE)
|
||
{
|
||
m_CurrentState = dsState_Xferring;
|
||
}
|
||
|
||
return twrc;
|
||
}
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::saveImageFileAsTIFF()
|
||
{
|
||
TW_INT32 nWidth = m_ImageInfo.ImageWidth;
|
||
TW_INT32 nHeight = m_ImageInfo.ImageLength;
|
||
TW_INT16 nBPP = m_ImageInfo.BitsPerPixel;
|
||
TW_INT32 nBPL = BYTES_PERLINE(nWidth, nBPP);
|
||
CTiffWriter *pTifImg = new CTiffWriter(m_CurFileExferName, nWidth, nHeight, nBPP, nBPL);
|
||
if(!pTifImg)
|
||
{
|
||
setConditionCode(TWCC_LOWMEMORY);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
pTifImg->setXResolution(m_ImageInfo.XResolution.Whole, 1);
|
||
pTifImg->setYResolution(m_ImageInfo.YResolution.Whole, 1);
|
||
pTifImg->writeImageHeader();
|
||
|
||
BYTE *pImage = (BYTE *)_DSM_LockMemory(m_hImageData);
|
||
if(pImage == NULL)
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
delete pTifImg;
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
bool bSwitch = true;
|
||
CTWAINContainerInt *pnCap = dynamic_cast<CTWAINContainerInt*>(findCapability(ICAP_BITORDER));
|
||
if(pnCap)
|
||
{
|
||
int nVal;
|
||
if(pnCap->GetCurrent(nVal))
|
||
{
|
||
bSwitch = nVal==TWBO_LSBFIRST? true:false;
|
||
}
|
||
}
|
||
|
||
// write the received image data to the image file
|
||
if( m_ImageInfo.BitsPerPixel < 24 // BW or Gray
|
||
|| m_ImageInfo.BitsPerPixel > 24 && !bSwitch) //Color but have to switch between RGB and BGR
|
||
{
|
||
if(!pTifImg->WriteTIFFData(reinterpret_cast<char*>(pImage), nBPL*nHeight))
|
||
{
|
||
setConditionCode(TWCC_FILEWRITEERROR);
|
||
_DSM_UnlockMemory(m_hImageData);
|
||
delete pTifImg;
|
||
return TWRC_FAILURE;
|
||
}
|
||
}
|
||
else // color
|
||
{
|
||
// we need to reverse the color from BRG to RGB
|
||
BYTE *pLineBuff = NULL;
|
||
TW_HANDLE hLineBuff = _DSM_Alloc(nBPL);
|
||
|
||
if( NULL == hLineBuff )
|
||
{
|
||
setConditionCode(TWCC_LOWMEMORY);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
pLineBuff = (BYTE*)_DSM_LockMemory(hLineBuff);
|
||
if(NULL == pLineBuff)
|
||
{
|
||
_DSM_Free(hLineBuff);
|
||
setConditionCode(TWCC_LOWMEMORY);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
BYTE *pSource = pImage;
|
||
BYTE *pDest = NULL;
|
||
|
||
|
||
for(TW_INT32 row=0; row<nHeight; row++)
|
||
{
|
||
pSource = pImage + row*nBPL;
|
||
pDest = pLineBuff;
|
||
|
||
// need to switch from BGR to RGB
|
||
for(TW_INT32 nCol=0; nCol<nWidth; nCol++)
|
||
{
|
||
*pDest++ = pSource[2];
|
||
*pDest++ = pSource[1];
|
||
*pDest++ = pSource[0];
|
||
pSource += 3;
|
||
}
|
||
|
||
// Save each line after it is converted.
|
||
if(!pTifImg->WriteTIFFData(reinterpret_cast<char*>(pLineBuff), nBPL))
|
||
{
|
||
setConditionCode(TWCC_FILEWRITEERROR);
|
||
_DSM_UnlockMemory(m_hImageData);
|
||
delete pTifImg;
|
||
return TWRC_FAILURE;
|
||
}
|
||
}
|
||
|
||
_DSM_UnlockMemory(hLineBuff);
|
||
_DSM_Free(hLineBuff);
|
||
|
||
}
|
||
delete pTifImg;
|
||
_DSM_UnlockMemory(m_hImageData);
|
||
|
||
return TWRC_XFERDONE;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::saveImageFileAsBMP()
|
||
{
|
||
// Save the image to disk
|
||
FILE *pFile;
|
||
FOPEN(pFile, m_CurFileExferName, "wb");
|
||
if(pFile == 0)
|
||
{
|
||
setConditionCode(TWCC_FILEWRITEERROR);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
TW_HANDLE hDIB = 0;
|
||
if( TWRC_SUCCESS != getDIBImage(hDIB) )
|
||
{
|
||
setConditionCode(TWCC_LOWMEMORY);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
// -Here we get a handle to a DIB. Save it to disk as a bmp.
|
||
PBITMAPINFOHEADER pDIB = (PBITMAPINFOHEADER)_DSM_LockMemory(hDIB);
|
||
if( pDIB == 0 )
|
||
{
|
||
setConditionCode(TWCC_LOWMEMORY);
|
||
_DSM_Free(hDIB);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
int nOffSet = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (sizeof(RGBQUAD)*pDIB->biClrUsed);
|
||
int nDIBSize = sizeof(BITMAPINFOHEADER) + (sizeof(RGBQUAD)*pDIB->biClrUsed) + pDIB->biSizeImage;
|
||
|
||
BITMAPFILEHEADER bmpFIH;
|
||
memset(&bmpFIH, 0, sizeof(BITMAPFILEHEADER));
|
||
bmpFIH.bfType = ( (WORD) ('M' << 8) | 'B');
|
||
bmpFIH.bfOffBits = nOffSet;
|
||
bmpFIH.bfSize = sizeof(BITMAPFILEHEADER) + nDIBSize;
|
||
|
||
fwrite(&bmpFIH, 1, sizeof(BITMAPFILEHEADER), pFile);
|
||
fwrite(pDIB, 1, nDIBSize, pFile);
|
||
fclose(pFile);
|
||
pFile = 0;
|
||
_DSM_UnlockMemory(hDIB);
|
||
_DSM_Free(hDIB);
|
||
|
||
return TWRC_XFERDONE;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::getDIBImage(TW_HANDLE& _hImage)
|
||
{
|
||
if( 0 == m_hImageData )
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
return TWRC_FAILURE;
|
||
}
|
||
TW_INT16 twrc = TWRC_FAILURE;
|
||
_hImage = 0;
|
||
|
||
TW_HANDLE hDIB = NULL; //create a handle to a bitmap, which we'll allocate
|
||
BYTE *pSourceBuff = NULL;
|
||
BYTE *pDestBuff = NULL;
|
||
BYTE *pSrc = NULL;
|
||
BYTE *pDst = NULL;
|
||
|
||
PBITMAPINFOHEADER pDIBInfoHeader = NULL;
|
||
const WORD bpp = m_ImageInfo.BitsPerPixel;
|
||
const DWORD SrcWidth = m_ImageInfo.ImageWidth;
|
||
const DWORD SrcLength = m_ImageInfo.ImageLength;
|
||
const DWORD SrcBytesPerRow = BYTES_PERLINE(SrcWidth, bpp);
|
||
const DWORD DstBytesPerRowAlgn = BYTES_PERLINE_ALIGN4(SrcWidth, bpp); //get the number of bytes per line we'll need for this image, and make sure it's DWORD-aligned
|
||
const WORD numcolors = bpp==1?2:bpp==8?256:0;// B&W = 2, Grey = 256, Color = 0
|
||
const WORD palettesize = sizeof(RGBQUAD)* numcolors;
|
||
const DWORD bitmapSize = sizeof(BITMAPINFOHEADER) + palettesize + DstBytesPerRowAlgn*SrcLength; //multiply the bytes-per-row by the number of scanlines, and add that to the size of the bitmap header to find the total size of the bitmap
|
||
|
||
|
||
try
|
||
{
|
||
pSourceBuff = (BYTE *)_DSM_LockMemory(m_hImageData);
|
||
if(pSourceBuff == NULL)
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
throw TWCC_BADVALUE;
|
||
}
|
||
|
||
hDIB = _DSM_Alloc(bitmapSize); //create a buffer as large as the bitmap
|
||
if(hDIB==NULL) //if we couldn't allocate the memory
|
||
{
|
||
//show that we ran out of memory
|
||
setConditionCode(TWCC_LOWMEMORY);
|
||
throw TWCC_LOWMEMORY;
|
||
}
|
||
|
||
pDIBInfoHeader=(PBITMAPINFOHEADER)_DSM_LockMemory(hDIB); //get a pointer to the bitmap info header
|
||
if(pDIBInfoHeader==NULL)
|
||
{
|
||
//show that we ran out of memory
|
||
setConditionCode(TWCC_LOWMEMORY);
|
||
throw TWCC_LOWMEMORY;
|
||
}
|
||
|
||
pDIBInfoHeader->biSize = sizeof(BITMAPINFOHEADER); //show how big the header info is
|
||
pDIBInfoHeader->biWidth = SrcWidth; //show how wide the image is
|
||
pDIBInfoHeader->biHeight = SrcLength; //show how tall the image is //G***shouldn't this be a negative number?
|
||
pDIBInfoHeader->biPlanes = 1; //bitmaps only support one color plane
|
||
pDIBInfoHeader->biBitCount = bpp; //set the bit depth
|
||
pDIBInfoHeader->biCompression = 0; //we only support uncompressed bitmaps
|
||
pDIBInfoHeader->biSizeImage = DstBytesPerRowAlgn*SrcLength; //uncompressed bitmaps can just set the size to zero
|
||
pDIBInfoHeader->biXPelsPerMeter = static_cast<LONG>(FIX32ToFloat(m_ImageInfo.XResolution) * 39.37F + 0.5);
|
||
pDIBInfoHeader->biYPelsPerMeter = static_cast<LONG>(FIX32ToFloat(m_ImageInfo.YResolution) * 39.37F + 0.5);
|
||
pDIBInfoHeader->biClrUsed = numcolors;
|
||
pDIBInfoHeader->biClrImportant = numcolors; //all the colors are important
|
||
|
||
_DSM_UnlockMemory(hDIB); //unlock our DIB memory
|
||
|
||
// Add Pallette
|
||
pDestBuff =(BYTE*)_DSM_LockMemory(hDIB); //get a pointer to the destination data
|
||
if(pDestBuff==NULL)
|
||
{
|
||
//show that we ran out of memory
|
||
setConditionCode(TWCC_LOWMEMORY);
|
||
throw TWCC_LOWMEMORY;
|
||
}
|
||
|
||
pDst = pDestBuff + sizeof(BITMAPINFOHEADER);
|
||
|
||
//fill the bitmap palette
|
||
if(numcolors==2)
|
||
{
|
||
RGBQUAD *pPal = (RGBQUAD*)pDst;
|
||
pPal->rgbBlue = pPal->rgbGreen = pPal->rgbRed = 0x00;
|
||
pPal->rgbReserved = 0x00;
|
||
|
||
pPal++;
|
||
pPal->rgbBlue = pPal->rgbGreen =pPal->rgbRed = 0xff;
|
||
pPal->rgbReserved = 0x00;
|
||
}
|
||
else if(numcolors==256)
|
||
{
|
||
RGBQUAD *pPal = (RGBQUAD*)pDst;
|
||
for(int iPal = 0; iPal <= 255; iPal++, pPal++)
|
||
{
|
||
pPal->rgbBlue = pPal->rgbGreen = pPal->rgbRed = iPal;
|
||
pPal->rgbReserved = 0x00;
|
||
}
|
||
}
|
||
pDst += palettesize;
|
||
|
||
bool bSwitch = false;
|
||
CTWAINContainerInt *pnCap = dynamic_cast<CTWAINContainerInt*>(findCapability(ICAP_BITORDER));
|
||
if(pnCap)
|
||
{
|
||
int nVal;
|
||
if(pnCap->GetCurrent(nVal))
|
||
{
|
||
bSwitch = nVal==TWBO_LSBFIRST? false:true;
|
||
// bSwitch=true;
|
||
}
|
||
}
|
||
|
||
// flip the image top to bottom
|
||
// for color change from BGR to RGB
|
||
if(TWPT_RGB==m_ImageInfo.PixelType && bSwitch)
|
||
{
|
||
for(DWORD length=0; length<SrcLength; length++)
|
||
{
|
||
pSrc = pSourceBuff + ( SrcBytesPerRow*(SrcLength-length-1) );
|
||
// need to switch from BGR to RGB
|
||
for(WORD nCol = 0; nCol<m_ImageInfo.ImageWidth; nCol++)
|
||
{
|
||
pDst[(nCol*3)] = pSrc[FI_RGBA_RED];
|
||
pDst[(nCol*3)+1] = pSrc[FI_RGBA_GREEN];
|
||
pDst[(nCol*3)+2] = pSrc[FI_RGBA_BLUE];
|
||
pSrc += 3;
|
||
}
|
||
pDst += DstBytesPerRowAlgn;
|
||
}
|
||
}
|
||
else // BW or Gray or color that does not need flipped
|
||
{
|
||
pSrc = pSourceBuff + ( SrcBytesPerRow*(SrcLength-1) );
|
||
for(DWORD length=0; length<SrcLength; length++)
|
||
{
|
||
memcpy(pDst, pSrc, SrcBytesPerRow);
|
||
pDst += DstBytesPerRowAlgn;
|
||
pSrc -= SrcBytesPerRow;
|
||
}
|
||
|
||
}
|
||
|
||
twrc = TWRC_SUCCESS;
|
||
_hImage = hDIB;
|
||
|
||
} // try
|
||
catch (WORD wConditionCodeError)
|
||
{
|
||
setConditionCode(wConditionCodeError);
|
||
// in the future we will have logging implemented and the wConditionCodeError will be recorded
|
||
_hImage = 0;
|
||
}
|
||
|
||
// cleanup
|
||
if(pSourceBuff)
|
||
{
|
||
_DSM_UnlockMemory(m_hImageData);
|
||
}
|
||
|
||
if(pDestBuff)
|
||
{
|
||
_DSM_UnlockMemory(hDIB);
|
||
}
|
||
|
||
if(twrc != TWRC_SUCCESS)
|
||
{
|
||
if(hDIB)
|
||
_DSM_Free(hDIB);
|
||
}
|
||
|
||
return twrc;
|
||
}
|
||
#ifdef TWNDS_OS_APPLE
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::getPICTImage(TW_HANDLE &_hPICTImage)
|
||
{
|
||
TW_INT16 twrc = TWRC_FAILURE;
|
||
if( 0 == m_hImageData )
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
TW_HANDLE _hTIFFdata;
|
||
twrc = getTIFFImage(_hTIFFdata);
|
||
if(twrc!=TWRC_SUCCESS)
|
||
{
|
||
return twrc;
|
||
}
|
||
|
||
twrc = TWRC_FAILURE;
|
||
setConditionCode(TWCC_BUMMER);
|
||
|
||
Handle dataRef = nil;
|
||
OSErr err = PtrToHand( &_hTIFFdata, &dataRef, sizeof(Handle));
|
||
if(err)
|
||
{
|
||
return twrc;
|
||
}
|
||
|
||
GraphicsImportComponent gi;
|
||
GetGraphicsImporterForDataRef(dataRef, HandleDataHandlerSubType, &gi);
|
||
|
||
if(gi)
|
||
{
|
||
PicHandle ph;
|
||
|
||
if (GraphicsImportGetAsPicture(gi, &ph) == noErr)
|
||
{
|
||
// Whew! We now have a PicHandle. Unfortunately, the caller
|
||
// expects a normal Handle. Copy the data and kill the picture.
|
||
UInt32 pictSize = GetHandleSize((Handle) ph);
|
||
Handle dataHandle = NewHandle(pictSize);
|
||
|
||
if (dataHandle && MemError() == noErr)
|
||
{
|
||
BlockMoveData(*ph, *dataHandle, pictSize);
|
||
_hPICTImage = dataHandle;
|
||
twrc = TWRC_SUCCESS;
|
||
setConditionCode(TWCC_SUCCESS);
|
||
}
|
||
KillPicture(ph);
|
||
}
|
||
|
||
CloseComponent(gi);
|
||
}
|
||
_DSM_Free(_hTIFFdata);
|
||
return twrc;
|
||
}
|
||
#endif
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::getTIFFImage(TW_HANDLE &_hTIFFImage)
|
||
{
|
||
if( 0 == m_hImageData )
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
_hTIFFImage = 0;
|
||
BYTE *pImage = (BYTE *)_DSM_LockMemory(m_hImageData);
|
||
if(pImage == NULL)
|
||
{
|
||
setConditionCode(TWCC_LOWMEMORY);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
TW_INT32 nWidth = m_ImageInfo.ImageWidth;
|
||
TW_INT32 nHeight = m_ImageInfo.ImageLength;
|
||
TW_INT16 nBPP = m_ImageInfo.BitsPerPixel;
|
||
TW_INT32 nBPL = BYTES_PERLINE(nWidth, nBPP);
|
||
CTiffWriter *pTifImg = new CTiffWriter("", nWidth, nHeight, nBPP, nBPL);
|
||
if(!pTifImg)
|
||
{
|
||
setConditionCode(TWCC_LOWMEMORY);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
pTifImg->setXResolution(m_ImageInfo.XResolution.Whole, 1);
|
||
pTifImg->setYResolution(m_ImageInfo.YResolution.Whole, 1);
|
||
|
||
stringstream Header;
|
||
pTifImg->GetImageHeader(Header);
|
||
Header.seekp(0, ios_base::end);
|
||
DWORD dwSize =(DWORD) Header.tellp();
|
||
Header.seekg(0, ios_base::beg);
|
||
TW_HANDLE hTiff = _DSM_Alloc(dwSize+nBPL*nHeight); //create a buffer as large as the bitmap
|
||
if(hTiff==0)
|
||
{
|
||
setConditionCode(TWCC_LOWMEMORY);
|
||
delete pTifImg;
|
||
return TWRC_FAILURE;
|
||
}
|
||
char *pData = (char*)_DSM_LockMemory(hTiff);
|
||
if(pData==0)
|
||
{
|
||
_DSM_Free(hTiff);
|
||
setConditionCode(TWCC_LOWMEMORY);
|
||
delete pTifImg;
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
Header.read(pData,dwSize);
|
||
pData +=dwSize;
|
||
|
||
bool bSwitch = true;
|
||
CTWAINContainerInt *pnCap = dynamic_cast<CTWAINContainerInt*>(findCapability(ICAP_BITORDER));
|
||
if(pnCap)
|
||
{
|
||
int nVal;
|
||
if(pnCap->GetCurrent(nVal))
|
||
{
|
||
bSwitch = nVal==TWBO_LSBFIRST? true:false;
|
||
}
|
||
}
|
||
|
||
// write the received image data to the image file
|
||
if( m_ImageInfo.BitsPerPixel < 24 // BW or Gray
|
||
|| m_ImageInfo.BitsPerPixel > 24 && !bSwitch) //Color but have to switch between RGB and BGR
|
||
{
|
||
memcpy(pData,pImage,nBPL*nHeight);
|
||
}
|
||
else // color
|
||
{
|
||
BYTE *pSource = pImage;
|
||
BYTE *pDest = NULL;
|
||
|
||
|
||
for(TW_INT32 row=0; row<nHeight; row++)
|
||
{
|
||
pSource = pImage;
|
||
pDest = (BYTE*)pData;
|
||
|
||
// need to switch from BGR to RGB
|
||
for(TW_INT32 nCol=0; nCol<nWidth; nCol++)
|
||
{
|
||
*pDest++ = pSource[2];
|
||
*pDest++ = pSource[1];
|
||
*pDest++ = pSource[0];
|
||
pSource += 3;
|
||
}
|
||
pData += nBPL;
|
||
pImage += nBPL;
|
||
}
|
||
}
|
||
|
||
delete pTifImg;
|
||
_DSM_UnlockMemory(m_hImageData);
|
||
_DSM_UnlockMemory(hTiff);
|
||
_hTIFFImage = hTiff;
|
||
|
||
return TWRC_SUCCESS;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::transferMemoryBuffers(pTW_IMAGEMEMXFER _ImageXfer)
|
||
{
|
||
TW_INT16 twrc = TWRC_SUCCESS;
|
||
|
||
if( !( dsState_XferReady == m_CurrentState ||
|
||
dsState_Xferring == m_CurrentState ) )
|
||
{
|
||
setConditionCode(TWCC_SEQERROR);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
DWORD nDestBytesPerRow = BYTES_PERLINE_ALIGN4(m_ImageInfo.ImageWidth, m_ImageInfo.BitsPerPixel);
|
||
DWORD nSrcBytesPerRow = BYTES_PERLINE(m_ImageInfo.ImageWidth, m_ImageInfo.BitsPerPixel);
|
||
|
||
if(_ImageXfer->Memory.Length < nDestBytesPerRow)
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
if(0 == m_nDestScanLine)
|
||
{
|
||
// Get the image that should be waiting for us.
|
||
transfer();
|
||
}
|
||
|
||
if(0 == m_hImageData)
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
BYTE *pSourceBuff = (BYTE *)_DSM_LockMemory(m_hImageData);
|
||
if(pSourceBuff == NULL)
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
BYTE *pDestBuff = 0;
|
||
if(TWMF_POINTER & _ImageXfer->Memory.Flags)
|
||
{
|
||
pDestBuff = (BYTE*)_ImageXfer->Memory.TheMem;
|
||
}
|
||
else if(TWMF_HANDLE & _ImageXfer->Memory.Flags)
|
||
{
|
||
pDestBuff = (BYTE*)_DSM_LockMemory((TW_HANDLE)(_ImageXfer->Memory.TheMem));
|
||
}
|
||
if(pDestBuff == NULL)
|
||
{
|
||
setConditionCode(TWCC_BADVALUE);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
m_CurrentState = dsState_Xferring;
|
||
|
||
DWORD nRows = MIN(_ImageXfer->Memory.Length / nDestBytesPerRow, m_ImageInfo.ImageLength-m_nDestScanLine);
|
||
|
||
bool bSwitch = true;
|
||
CTWAINContainerInt *pnCap = dynamic_cast<CTWAINContainerInt*>(findCapability(ICAP_BITORDER));
|
||
if(pnCap)
|
||
{
|
||
int nVal;
|
||
if(pnCap->GetCurrent(nVal))
|
||
{
|
||
bSwitch = nVal==TWBO_LSBFIRST? true:false;
|
||
}
|
||
}
|
||
|
||
BYTE *pSrc = 0;
|
||
BYTE *pDst = pDestBuff;
|
||
// for color change from BGR to RGB
|
||
if(TWPT_RGB==m_ImageInfo.PixelType && bSwitch)
|
||
{
|
||
for(DWORD row=0; row<nRows; row++)
|
||
{
|
||
pSrc = pSourceBuff + nSrcBytesPerRow * (m_nDestScanLine+row);
|
||
pDst = pDestBuff + nDestBytesPerRow * row;
|
||
// need to switch from BGR to RGB
|
||
for(WORD nCol = 0; nCol<m_ImageInfo.ImageWidth; nCol++)
|
||
{
|
||
*pDst++ = pSrc[2];
|
||
*pDst++ = pSrc[1];
|
||
*pDst++ = pSrc[0];
|
||
pSrc += 3;
|
||
}
|
||
}
|
||
}
|
||
else // BW or Gray or Color that does not need to be flipped
|
||
{
|
||
pSrc = pSourceBuff + nSrcBytesPerRow*(m_nDestScanLine);
|
||
for(DWORD row=0; row<nRows; row++)
|
||
{
|
||
memcpy(pDst, pSrc, nSrcBytesPerRow);
|
||
pDst += nDestBytesPerRow;
|
||
pSrc += nSrcBytesPerRow;
|
||
}
|
||
}
|
||
|
||
//uncompressed image data
|
||
_ImageXfer->Compression = m_ImageInfo.Compression;
|
||
//bytes per row (DWORD aligned as per spec)
|
||
_ImageXfer->BytesPerRow = nDestBytesPerRow;
|
||
//width in pixels
|
||
_ImageXfer->Columns = m_ImageInfo.ImageWidth;
|
||
//X offset always 0, only used in tiled images - obsolete
|
||
_ImageXfer->XOffset = 0;
|
||
//position of this strip from the beginning of the image
|
||
_ImageXfer->YOffset = m_nDestScanLine;
|
||
//update the number of rows and bytes written
|
||
_ImageXfer->Rows= nRows;
|
||
_ImageXfer->BytesWritten = nDestBytesPerRow*nRows;
|
||
|
||
// increment the current scanline for next pass
|
||
m_nDestScanLine+=nRows;
|
||
|
||
// check for finished scan
|
||
if(m_nDestScanLine >= (DWORD)m_ImageInfo.ImageLength)
|
||
{
|
||
//we are done early
|
||
m_nDestScanLine = 0;
|
||
twrc = TWRC_XFERDONE;
|
||
}
|
||
|
||
_DSM_UnlockMemory(m_hImageData);
|
||
|
||
if(TWMF_HANDLE & _ImageXfer->Memory.Flags)
|
||
{
|
||
_DSM_UnlockMemory((TW_HANDLE)(_ImageXfer->Memory.TheMem));
|
||
}
|
||
|
||
return twrc;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::transferNativeImage(TW_HANDLE &_hData)
|
||
{
|
||
TW_INT16 twrc = TWRC_FAILURE;
|
||
|
||
if( dsState_XferReady != m_CurrentState )
|
||
{
|
||
setConditionCode(TWCC_SEQERROR);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
// Get the image that should be waiting for us.
|
||
twrc = transfer();
|
||
if(TWRC_SUCCESS == twrc)
|
||
{
|
||
// Native is basicaly an image file transfered by memory
|
||
// Windows is a Device independent BMP
|
||
// Mac has changed from a PICT to a TIFF
|
||
// Linux is a TIFF
|
||
#if defined(TWNDS_OS_LINUX)
|
||
twrc = getTIFFImage(_hData);
|
||
#elif defined(TWNDS_OS_APPLE)
|
||
twrc = getPICTImage(_hData);
|
||
#else
|
||
twrc = getDIBImage(_hData);
|
||
#endif
|
||
if( TWRC_SUCCESS == twrc )
|
||
{
|
||
#if !defined(TWNDS_OS_APPLE)
|
||
twrc = TWRC_XFERDONE;
|
||
#endif
|
||
m_CurrentState = dsState_Xferring;
|
||
}
|
||
}
|
||
|
||
return twrc;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::GetGustomDSData(pTW_CUSTOMDSDATA _pDSData)
|
||
{
|
||
setConditionCode(TWCC_BADPROTOCOL);
|
||
return TWRC_FAILURE;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
TW_INT16 CTWAINDS_Base::SetGustomDSData(pTW_CUSTOMDSDATA _pDSData)
|
||
{
|
||
setConditionCode(TWCC_BADPROTOCOL);
|
||
return TWRC_FAILURE;
|
||
} |