|
|
#include "precomp.h"
// #define DEBUG_MEMXFER
#define PRIVATE_CAP_ARRAY_PADDING 64 // 64 bytes padding
const TCHAR WIA_STR[] = TEXT("WIA-"); const CHAR* FAMILY_NAME = "Twain Data Source On WIA";
CWiaDataSrc::CWiaDataSrc() : m_dsState(DS_STATE_0), m_hMemXferBits(NULL), m_pMemXferBits(NULL), m_pDevice(NULL), m_pIWiaItems(NULL), m_NumIWiaItems(0), m_NextIWiaItemIndex(0), m_NumCaps(0), m_CapList(NULL), m_hCachedImageData(NULL), m_bCacheImage(FALSE) { SetTWAINState(DS_STATE_3); memset(m_FileXferName,0,sizeof(m_FileXferName)); memset(&m_AppIdentity,0,sizeof(m_AppIdentity)); memset(&m_dsIdentity,0, sizeof(m_dsIdentity)); memset(&m_CurFrame, 0,sizeof(m_CurFrame)); memset(&m_CurImageLayout, 0,sizeof(m_CurImageLayout)); memset(&m_MemoryTransferInfo,0,sizeof(m_MemoryTransferInfo));
ResetMemXfer();
m_twStatus.ConditionCode = TWCC_SUCCESS;
m_CurImageLayout.DocumentNumber = 1; m_CurImageLayout.PageNumber = 1; m_CurImageLayout.FrameNumber = 1; m_CurImageLayout.Frame.Top.Whole = 0; m_CurImageLayout.Frame.Top.Frac = 0; m_CurImageLayout.Frame.Left.Whole = 0; m_CurImageLayout.Frame.Left.Frac = 0; m_CurImageLayout.Frame.Right.Whole = 8; m_CurImageLayout.Frame.Right.Frac = 5; m_CurImageLayout.Frame.Bottom.Whole = 11; m_CurImageLayout.Frame.Bottom.Frac = 0; m_pCurrentIWiaItem = NULL; }
CWiaDataSrc::~CWiaDataSrc() { ResetMemXfer(); if (m_pDevice){ delete m_pDevice; m_pDevice = NULL; }
if (m_pIWiaItems){ delete [] m_pIWiaItems; m_pIWiaItems = NULL; } }
TW_UINT16 CWiaDataSrc::IWiaDataSrc(LPCTSTR DeviceId) { if (!DeviceId) { m_twStatus.ConditionCode = TWCC_BADVALUE; return TWRC_FAILURE; }
//
// Initialize m_dsIdentity. This is required because
// DG_CONTROL/DAT_IDENTITY/MSG_GET could be called
// before we are opened.
//
m_pDevice = new CWiaDevice;
if (!m_pDevice) { m_twStatus.ConditionCode = TWCC_LOWMEMORY; return TWRC_FAILURE; }
TCHAR szTempString[MAX_PATH]; memset(szTempString,0,sizeof(szTempString));
HRESULT hr = S_OK;
hr = m_pDevice->Initialize(DeviceId); if (FAILED(hr)) { m_twStatus.ConditionCode = TWCC_LOWMEMORY; delete m_pDevice; m_pDevice = NULL; DBG_ERR(("CWiaDataSrc::IWiaDataSrc(), WIA Device object Initialize failed")); return TWRC_FAILURE; }
//
// We don't need to attach a callback here because we will
// close the device after we are done with it.
//
if (SUCCEEDED(hr)) { m_dsIdentity.Id = 0; m_dsIdentity.Version.MajorNum = 1; m_dsIdentity.Version.MinorNum = 0; m_dsIdentity.Version.Language = TWLG_USA; m_dsIdentity.Version.Country = TWCY_USA; m_dsIdentity.ProtocolMajor = TWON_PROTOCOLMAJOR; m_dsIdentity.ProtocolMinor = TWON_PROTOCOLMINOR; m_dsIdentity.SupportedGroups = DG_CONTROL | DG_IMAGE; lstrcpyA(m_dsIdentity.Version.Info,"26 June 2000");
//
// Use a specific product family name so that applications
// can differentiate between a data source on WIA and
// a *pure* TWAIN data source
//
lstrcpyA(m_dsIdentity.ProductFamily, FAMILY_NAME); lstrcpyA(m_dsIdentity.ProductName, "UnknownProduct"); lstrcpyA(m_dsIdentity.Manufacturer, "UnknownMfg");
#ifdef UNICODE
//
// UNICODE specific
//
// This assumes that ProductName, FamilyName and Manufacturer
// are all in TW_STR32 (TWAIN data type for a string).
//
UINT Len = 0; memset(szTempString,0,sizeof(szTempString)); hr = m_pDevice->GetDeviceDesc(szTempString,sizeof(szTempString),&Len); if (SUCCEEDED(hr)) {
//
// Add "WIA-" to beginning of ProductName string, to separate
// TWAIN installed data sources, from WIA data sources
//
AddWIAPrefixToString(szTempString,sizeof(szTempString)); Len += lstrlen(WIA_STR); // add prefix size to length
//
// set ProductName in TW_IDENTITY structure
//
WideCharToMultiByte(CP_ACP, 0, szTempString, Len + 1,m_dsIdentity.ProductName, (sizeof(m_dsIdentity.ProductName)/sizeof(m_dsIdentity.ProductName[0])),NULL, NULL);
Len = 0; } else { DBG_ERR(("CWiaDataSrc::IWiaDataSrc(), GetDeviceDesc failed")); return TWRC_FAILURE; }
memset(szTempString,0,sizeof(szTempString)); hr = m_pDevice->GetDeviceVendorName(szTempString,sizeof(szTempString),&Len); if (SUCCEEDED(hr)) {
//
// set Manufacturer in TW_IDENTITY structure
//
WideCharToMultiByte(CP_ACP, 0, szTempString, Len + 1,m_dsIdentity.Manufacturer, (sizeof(m_dsIdentity.Manufacturer)/sizeof(m_dsIdentity.Manufacturer[0])),NULL, NULL); } else { DBG_ERR(("CWiaDataSrc::IWiaDataSrc(), GetDeviceVendorName failed")); return TWRC_FAILURE; }
#else
//
// ANSI specific
//
memset(szTempString,0,sizeof(szTempString)); hr = m_pDevice->GetDeviceDesc(szTempString,sizeof(szTempString),NULL); if (SUCCEEDED(hr) ) {
//
// Add "WIA-" to beginning of ProductName string, to separate
// TWAIN installed data sources, from WIA data sources
//
AddWIAPrefixToString(szTempString,sizeof(szTempString));
//
// set ProductName in TW_IDENTITY structure
//
strncpy(m_dsIdentity.ProductName,szTempString,sizeof(TW_STR32) - 1);
} else { DBG_ERR(("CWiaDataSrc::IWiaDataSrc(),GetDeviceDesc failed")); return TWRC_FAILURE; }
memset(szTempString,0,sizeof(szTempString)); hr = m_pDevice->GetDeviceVendorName(szTempString,sizeof(szTempString),NULL); if (SUCCEEDED(hr) ) {
//
// set Manufacturer in TW_IDENTITY structure
//
strncpy(m_dsIdentity.Manufacturer,szTempString,sizeof(TW_STR32) - 1); } else { DBG_ERR(("CWiaDataSrc::IWiaDataSrc(),GetDeviceVendorName failed")); } #endif
} return(SUCCEEDED(hr)) ? TWRC_SUCCESS : TWRC_FAILURE; }
TW_UINT16 CWiaDataSrc::AddWIAPrefixToString(LPTSTR szString,UINT uSize) { TCHAR szTempBuffer[512]; memset(szTempBuffer,0,sizeof(szTempBuffer)); _sntprintf(szTempBuffer,(sizeof(szTempBuffer)/sizeof(szTempBuffer[0])),TEXT("%s%s"),WIA_STR,szString); szTempBuffer[(sizeof(szTempBuffer)/sizeof(szTempBuffer[0])) - 1] = 0;
//
// copy, and truncate New string to TWAIN's required
// restricted size.
//
memset(szString,0,uSize);
#ifdef UNICODE
wcsncpy(szString,szTempBuffer,(sizeof(TW_STR32) - 1)); #else
strncpy(szString,szTempBuffer,(sizeof(TW_STR32) - 1)); #endif
return TWRC_SUCCESS; }
TW_UINT16 CWiaDataSrc::DSEntry(pTW_IDENTITY pOrigin,TW_UINT32 DG,TW_UINT16 DAT, TW_UINT16 MSG,TW_MEMREF pData) { TWAIN_MSG twMsg; twMsg.AppId = pOrigin; twMsg.DG = DG; twMsg.DAT = DAT; twMsg.MSG = MSG; twMsg.pData = pData;
TW_UINT16 twRc = TWRC_SUCCESS;
if (MSG_PROCESSEVENT == MSG) { //
// Since we rely on WIA UI to provide the user interface and since
// the WIA UI is a modal dialog box(meaning it has its own
// messge loop), every event we receive here is not DS event.
//
//((TW_EVENT*)twMsg.pData)->TWMessage = MSG_NULL;
twRc = TWRC_NOTDSEVENT; } else { //
// Dispatch message based on group
//
switch (twMsg.DG) { case DG_CONTROL: twRc = DispatchControlMsg(&twMsg); break; case DG_IMAGE: twRc = DispatchImageMsg(&twMsg); break; default: m_twStatus.ConditionCode = TWCC_BADPROTOCOL; twRc = TWRC_FAILURE; break; } DBG_TRC(("Sent to TWAIN Application, DG = %X, DT = %X, MSG = %X, ( TWRC = %X, TWCC = %X)",DG,DAT,MSG,twRc,m_twStatus.ConditionCode)); } return twRc; }
#ifdef _USE_NONSPRINTF_CONVERSION
float CWiaDataSrc::Fix32ToFloat(TW_FIX32 fix32) { float ffloat = 0.0f;
//
// TWAIN spec implementation
//
ffloat = (float)fix32.Whole + (float)fix32.Frac / 65536.0f;
/*
//
// original implementation
//
int iexp = 1; int frac = fix32.Frac; while(frac/10 > 0){ iexp++; frac = (frac/10); } ffloat = (float)fix32.Whole + (float) ( (float) fix32.Frac / (float) pow(10,iexp));
*/
return ffloat; }
TW_FIX32 CWiaDataSrc::FloatToFix32(float ffloat) { TW_FIX32 fix32; memset(&fix32,0,sizeof(fix32));
//
// TWAIN spec implementation
//
TW_INT32 value = (TW_INT32) (ffloat * 65536.0f + 0.5f); fix32.Whole = (TW_INT16)(value >> 16); fix32.Frac = (TW_UINT16)(value & 0x0000ffffL);
/*
//
// original implementation
//
fix32.Whole = (TW_INT16)ffloat; //float fVal = -((float)fix32.Whole - ffloat);
float fVal = (ffloat - (float)fix32.Whole); fVal = (fVal * 100000.0f); fix32.Frac = (TW_UINT16)(fVal); */
return fix32; }
#else // _USE_NONSPRINTF_CONVERSION
TW_FIX32 CWiaDataSrc::FloatToFix32(float f) { char fstr[64]; memset(fstr,0,sizeof(fstr)); char *p = NULL; TW_FIX32 f32; memset(&f32,0,sizeof(f32));
sprintf(fstr, "%f", f); p = strchr(fstr, '.'); if (p != NULL) { *p = '\0'; f32.Whole = (TW_INT16)atoi(fstr); f32.Frac = (TW_UINT16)atoi(p + 1); } return f32; }
float CWiaDataSrc::Fix32ToFloat(TW_FIX32 fix32) {
// (full precision)
char fstr[64]; memset(fstr,0,sizeof(fstr)); float fReturnValue = 0.0f; sprintf(fstr,"%d.%d",fix32.Whole,fix32.Frac); sscanf(fstr,"%f",&fReturnValue);
// original (loses precision)
// fReturnValue = (float)fix32.Whole + (float)(fix32.Frac / 65536.0);
return fReturnValue; } #endif // _USE_NONSPRINTF_CONVERSION
void CWiaDataSrc::NotifyCloseReq() { DBG_FN_DS(CWiaDataSrc::NotifyCloseReq()); if(m_DSM.Notify(&m_dsIdentity, &m_AppIdentity, (TW_UINT32)DG_CONTROL, DAT_NULL,MSG_CLOSEDSREQ, (TW_MEMREF)NULL)){ DBG_TRC(("CWiaDataSrc::NotifyCloseReq(), MSG_CLOSEDSREQ is sent to application")); } else { DBG_WRN(("CWiaDataSrc::NotifyCloseReq(), could not notify application for MSG_CLOSEDSREQ")); } }
void CWiaDataSrc::NotifyXferReady() { DBG_FN_DS(CWiaDataSrc::NotifyXferReady()); if (m_DSM.Notify(&m_dsIdentity,&m_AppIdentity, (TW_UINT32)DG_CONTROL,DAT_NULL,MSG_XFERREADY,(TW_MEMREF)NULL)) {
DBG_TRC(("CWiaDataSrc::NotifyXferReady(), MSG_XFERREADY is sent to application"));
//
// transition to STATE_6
//
SetTWAINState(DS_STATE_6);
} else { DBG_WRN(("CWiaDataSrc::NotifyXferReady(), could not notify application for MSG_XFERREADY")); } }
void CWiaDataSrc::ResetMemXfer() { DBG_FN_DS(CWiaDataSrc::ResetMemXfer()); if (IS_VALID_HANDLE(m_hMemXferBits)) { if (m_pMemXferBits) { if (GlobalUnlock(m_hMemXferBits)) { m_pMemXferBits = NULL; } } // Now free block always
GlobalFree(m_hMemXferBits); } m_hMemXferBits = NULL; m_hCachedImageData = NULL; m_LinesTransferred = 0; }
TW_UINT16 CWiaDataSrc::DispatchControlMsg(PTWAIN_MSG ptwMsg) { TW_UINT16 twRc = TWRC_SUCCESS;
if (!ptwMsg) { m_twStatus.ConditionCode = TWCC_BADPROTOCOL; return TWRC_FAILURE; } switch (ptwMsg->DAT) { case DAT_IDENTITY: twRc = OnIdentityMsg(ptwMsg); break; case DAT_USERINTERFACE: twRc = OnUserInterfaceMsg(ptwMsg); break; case DAT_CAPABILITY: twRc = OnCapabilityMsg(ptwMsg); break; case DAT_STATUS: twRc = OnStatusMsg(ptwMsg); break; case DAT_PENDINGXFERS: twRc = OnPendingXfersMsg(ptwMsg); break; case DAT_SETUPMEMXFER: twRc = OnSetupMemXferMsg(ptwMsg); break; case DAT_SETUPFILEXFER: twRc = OnSetupFileXferMsg(ptwMsg); break; case DAT_XFERGROUP: twRc = OnXferGroupMsg(ptwMsg); break; default: twRc = TWRC_FAILURE; m_twStatus.ConditionCode = TWCC_BADPROTOCOL; } return twRc; }
TW_UINT16 CWiaDataSrc::DispatchImageMsg(PTWAIN_MSG ptwMsg) { TW_UINT16 twRc = TWRC_SUCCESS;
if (!ptwMsg) { m_twStatus.ConditionCode = TWCC_BADPROTOCOL; return TWRC_FAILURE; }
switch (ptwMsg->DAT) { case DAT_IMAGEINFO: twRc = OnImageInfoMsg(ptwMsg); break; case DAT_IMAGELAYOUT: twRc = OnImageLayoutMsg(ptwMsg); break; case DAT_IMAGEMEMXFER: twRc = OnImageMemXferMsg(ptwMsg); break; case DAT_IMAGENATIVEXFER: twRc = OnImageNativeXferMsg(ptwMsg); break; case DAT_IMAGEFILEXFER: twRc = OnImageFileXferMsg(ptwMsg); break; case DAT_PALETTE8: twRc = OnPalette8Msg(ptwMsg); break; case DAT_GRAYRESPONSE: twRc = OnGrayResponseMsg(ptwMsg); break; case DAT_RGBRESPONSE: twRc = OnRGBResponseMsg(ptwMsg); break; case DAT_CIECOLOR: twRc = OnCIEColorMsg(ptwMsg);; break; case DAT_JPEGCOMPRESSION: twRc = OnJPEGCompressionMsg(ptwMsg); break; default: twRc = TWRC_FAILURE; m_twStatus.ConditionCode = TWCC_BADPROTOCOL; } return twRc; }
TW_UINT16 CWiaDataSrc::OnPalette8Msg(PTWAIN_MSG ptwMsg) { DBG_FN_DS(CWiaDataSrc::OnPalette8Msg()); TW_UINT16 twRc = TWRC_SUCCESS; switch (GetTWAINState()) { case DS_STATE_4: case DS_STATE_5: case DS_STATE_6: case DS_STATE_7: switch (ptwMsg->MSG) { case MSG_GET:
// TWPA_RGB - color palette
// TWPA_GRAY - grayscale palette
// TWPA_CMY - CMY palette
((TW_PALETTE8 *)ptwMsg->pData)->NumColors = 0; ((TW_PALETTE8 *)ptwMsg->pData)->PaletteType = TWPA_RGB; break; case MSG_GETDEFAULT: case MSG_RESET: case MSG_SET: break; default: m_twStatus.ConditionCode = TWCC_BADPROTOCOL; twRc = TWRC_FAILURE; DSError(); } break; default: m_twStatus.ConditionCode = TWCC_SEQERROR; twRc = TWRC_FAILURE; DSError(); break; } return twRc; }
TW_UINT16 CWiaDataSrc::OnSetupMemXferMsg(PTWAIN_MSG ptwMsg) { DBG_FN_DS(CWiaDataSrc::OnSetupMemXferMsg()); TW_UINT16 twRc = TWRC_SUCCESS; TW_SETUPMEMXFER *pMemSetup = (TW_SETUPMEMXFER *)ptwMsg->pData;
switch (GetTWAINState()) { case DS_STATE_4: case DS_STATE_5: case DS_STATE_6: if (MSG_GET == ptwMsg->MSG) { if (pMemSetup) { pMemSetup->MinBufSize = MIN_MEMXFER_SIZE; pMemSetup->MaxBufSize = MAX_MEMXFER_SIZE; pMemSetup->Preferred = PREFERRED_MEMXFER_SIZE; } else { m_twStatus.ConditionCode = TWCC_BADVALUE; twRc = TWRC_FAILURE; } } else { m_twStatus.ConditionCode = TWCC_BADPROTOCOL; twRc = TWRC_FAILURE; DSError(); } break; default: m_twStatus.ConditionCode = TWCC_SEQERROR; twRc = TWRC_FAILURE; DSError(); break; } return twRc; }
TW_UINT16 CWiaDataSrc::OnSetupFileXferMsg(PTWAIN_MSG ptwMsg) { DBG_FN_DS(CWiaDataSrc::OnSetupFileXferMsg()); TW_UINT16 twRc = TWRC_SUCCESS; CCap *pImageXferCap = NULL; TW_SETUPFILEXFER *pFileXfer = NULL; switch (GetTWAINState()) { case DS_STATE_4: case DS_STATE_5: case DS_STATE_6: pFileXfer = (TW_SETUPFILEXFER *)ptwMsg->pData; pImageXferCap = FindCap(ICAP_IMAGEFILEFORMAT); switch (ptwMsg->MSG) { case MSG_GET: case MSG_GETDEFAULT: case MSG_GETCURRENT: if (pImageXferCap) { pFileXfer->Format = (TW_UINT16)pImageXferCap->GetCurrent(); pFileXfer->VRefNum = 0; pFileXfer->FileName[0] = 0; strcpy(pFileXfer->FileName, m_FileXferName); } else { twRc = TWRC_FAILURE; m_twStatus.ConditionCode = TWCC_BUMMER; } break; case MSG_SET: { strcpy(m_FileXferName, pFileXfer->FileName); pImageXferCap->SetCurrent((VOID*)&pFileXfer->Format); } break; default: twRc = TWRC_FAILURE; m_twStatus.ConditionCode = TWCC_BADPROTOCOL; DSError(); break; } break; default: twRc = TWRC_FAILURE; m_twStatus.ConditionCode = TWCC_SEQERROR; DSError(); break; } return twRc; }
TW_UINT16 CWiaDataSrc::OnXferGroupMsg(PTWAIN_MSG ptwMsg) { DBG_FN_DS(CWiaDataSrc::OnXferGroupMsg()); TW_UINT16 twRc = TWRC_SUCCESS; switch (GetTWAINState()) { case DS_STATE_4: case DS_STATE_5: case DS_STATE_6: switch (ptwMsg->MSG) { case MSG_GET: case MSG_GETDEFAULT: case MSG_GETCURRENT: case MSG_RESET: *((TW_UINT16 *)ptwMsg->pData) = DG_IMAGE; break; case MSG_SET: break; default: m_twStatus.ConditionCode = TWCC_BADPROTOCOL; twRc = TWRC_FAILURE; DSError(); break; } break; default: m_twStatus.ConditionCode = TWCC_SEQERROR; twRc = TWRC_FAILURE; DSError(); break; } return twRc; }
TW_UINT16 CWiaDataSrc::OnImageInfoMsg(PTWAIN_MSG ptwMsg) { DBG_FN_DS(CWiaDataSrc::OnImageInfoMsg()); TW_UINT16 twRc = TWRC_FAILURE; TW_IMAGEINFO *ptwImageInfo = NULL; if (DS_STATE_6 == GetTWAINState()) { if (MSG_GET == ptwMsg->MSG) { ptwImageInfo = (TW_IMAGEINFO *)ptwMsg->pData; HRESULT hr = S_OK; hr = m_pDevice->GetImageInfo(m_pCurrentIWiaItem, &m_MemoryTransferInfo); if (SUCCEEDED(hr)) {
ptwImageInfo->ImageWidth = (TW_INT32)m_MemoryTransferInfo.mtiWidthPixels; ptwImageInfo->ImageLength = (TW_INT32)m_MemoryTransferInfo.mtiHeightPixels; ptwImageInfo->BitsPerPixel = (TW_INT16)m_MemoryTransferInfo.mtiBitsPerPixel; ptwImageInfo->SamplesPerPixel = (TW_INT16)m_MemoryTransferInfo.mtiNumChannels; ptwImageInfo->Planar = (TW_BOOL)m_MemoryTransferInfo.mtiPlanar;
//
// adjust height for unknown length acquisitions
//
if(ptwImageInfo->ImageLength == 0){ DBG_WRN(("CWiaDataSrc::OnImageInfoMsg(), Possible unknown length device detected..checking cached height value")); ptwImageInfo->ImageLength = m_ImageHeight; if(ptwImageInfo->ImageLength == 0){ DBG_WRN(("CWiaDataSrc::OnImageInfoMsg(), no cached height available, defaulting to -1 (ICAP_UNDEFINEDIMAGESIZE support only)")); ptwImageInfo->ImageLength = -1; // unknown page length (only valid if TWAIN applications support ICAP_UNDEFINEDIMAGESIZE)
} else { DBG_TRC(("CWiaDataSrc::OnImageInfoMsg(), new height = %d",ptwImageInfo->ImageLength)); } }
//
// set PixelType to corresponding TWAIN pixel type
//
switch(m_MemoryTransferInfo.mtiDataType) { case WIA_DATA_THRESHOLD: ptwImageInfo->PixelType = TWPT_BW; break; case WIA_DATA_GRAYSCALE: ptwImageInfo->PixelType = TWPT_GRAY; break; case WIA_DATA_COLOR: default: ptwImageInfo->PixelType = TWPT_RGB; break; }
//
// set compression to NONE
//
ptwImageInfo->Compression = TWCP_NONE;
//
// Unit conversion.......
//
ptwImageInfo->XResolution = FloatToFix32((float)m_MemoryTransferInfo.mtiXResolution); ptwImageInfo->YResolution = FloatToFix32((float)m_MemoryTransferInfo.mtiYResolution);
twRc = TWRC_SUCCESS;
} else { m_twStatus.ConditionCode = TWCC_OPERATIONERROR; twRc = TWRC_FAILURE; }
if (TWRC_SUCCESS == twRc) { DBG_TRC(("CWiaDataSrc::OnImageInfoMsg(), Reported Image Information from data source")); DBG_TRC(("XResolution = %d.%d",ptwImageInfo->XResolution.Whole,ptwImageInfo->XResolution.Frac)); DBG_TRC(("YResolution = %d.%d",ptwImageInfo->YResolution.Whole,ptwImageInfo->YResolution.Frac)); DBG_TRC(("ImageWidth = %d",ptwImageInfo->ImageWidth)); DBG_TRC(("ImageLength = %d",ptwImageInfo->ImageLength)); DBG_TRC(("SamplesPerPixel = %d",ptwImageInfo->SamplesPerPixel));
memset(ptwImageInfo->BitsPerSample,0,sizeof(ptwImageInfo->BitsPerSample));
if (ptwImageInfo->BitsPerPixel < 24) { ptwImageInfo->BitsPerSample[0] = ptwImageInfo->BitsPerPixel; } else { for (int i = 0; i < ptwImageInfo->SamplesPerPixel; i++) { ptwImageInfo->BitsPerSample[i] = (ptwImageInfo->BitsPerPixel/ptwImageInfo->SamplesPerPixel); } } // (bpp / spp) = bps
DBG_TRC(("BitsPerSample = [%d],[%d],[%d],[%d],[%d],[%d],[%d],[%d]",ptwImageInfo->BitsPerSample[0], ptwImageInfo->BitsPerSample[1], ptwImageInfo->BitsPerSample[2], ptwImageInfo->BitsPerSample[3], ptwImageInfo->BitsPerSample[4], ptwImageInfo->BitsPerSample[5], ptwImageInfo->BitsPerSample[6], ptwImageInfo->BitsPerSample[7])); DBG_TRC(("BitsPerPixel = %d",ptwImageInfo->BitsPerPixel)); DBG_TRC(("Planar = %d",ptwImageInfo->Planar)); DBG_TRC(("PixelType = %d",ptwImageInfo->PixelType)); DBG_TRC(("Compression = %d",ptwImageInfo->Compression)); } } else { m_twStatus.ConditionCode = TWCC_BADPROTOCOL; twRc = TWRC_FAILURE; } } else { m_twStatus.ConditionCode = TWCC_SEQERROR; twRc = TWRC_FAILURE; } if (TWRC_SUCCESS != twRc) { DSError(); } return twRc; }
TW_UINT16 CWiaDataSrc::OnImageLayoutMsg(PTWAIN_MSG ptwMsg) { m_twStatus.ConditionCode = TWCC_BUMMER; return TWRC_FAILURE; }
TW_UINT16 CWiaDataSrc::OnGrayResponseMsg(PTWAIN_MSG ptwMsg) { m_twStatus.ConditionCode = TWCC_BUMMER; return TWRC_FAILURE; }
TW_UINT16 CWiaDataSrc::OnRGBResponseMsg(PTWAIN_MSG ptwMsg) { m_twStatus.ConditionCode = TWCC_BUMMER; return TWRC_FAILURE; }
TW_UINT16 CWiaDataSrc::OnCIEColorMsg(PTWAIN_MSG ptwMsg) { m_twStatus.ConditionCode = TWCC_BUMMER; return TWRC_FAILURE; }
TW_UINT16 CWiaDataSrc::OnJPEGCompressionMsg(PTWAIN_MSG ptwMsg) { m_twStatus.ConditionCode = TWCC_BUMMER; return TWRC_FAILURE; }
TW_UINT16 CWiaDataSrc::OnIdentityMsg(PTWAIN_MSG ptwMsg) { DBG_FN_DS(CWiaDataSrc::OnIdentityMsg()); TW_UINT16 twRc = TWRC_SUCCESS; if (ptwMsg) { switch (ptwMsg->MSG) { case MSG_OPENDS:
#ifdef DEBUG_ME
MessageBox(NULL,TEXT("MSG_OPENDS - Attach me to a debugger"),TEXT("Attach me to a debugger"),MB_OK); #endif
twRc = OpenDS(ptwMsg); break; case MSG_CLOSEDS: twRc = CloseDS(ptwMsg); break; case MSG_GET: if (!IsBadWritePtr(ptwMsg->pData, sizeof(TW_IDENTITY))) { *(TW_IDENTITY*)ptwMsg->pData = m_dsIdentity; DBG_TRC(("CWiaDataSrc::OnIdentityMsg(), Reported TW_IDENTITY from data source")); DBG_TRC(("Id = %d",m_dsIdentity.Id)); DBG_TRC(("Manufacturer = %s",m_dsIdentity.Manufacturer)); DBG_TRC(("ProductFamily = %s",m_dsIdentity.ProductFamily)); DBG_TRC(("ProductName = %s",m_dsIdentity.ProductName)); DBG_TRC(("ProtocolMajor = %d",m_dsIdentity.ProtocolMajor)); DBG_TRC(("ProtocolMinor = %d",m_dsIdentity.ProtocolMinor)); DBG_TRC(("SupportedGrps = %d",m_dsIdentity.SupportedGroups)); DBG_TRC(("Ver Country = %d",m_dsIdentity.Version.Country)); DBG_TRC(("Ver Info = %s",m_dsIdentity.Version.Info)); DBG_TRC(("Ver Language = %d",m_dsIdentity.Version.Language)); DBG_TRC(("Ver MajorNum = %d",m_dsIdentity.Version.MajorNum)); DBG_TRC(("Ver MinorNum = %d",m_dsIdentity.Version.MinorNum)); twRc = TWRC_SUCCESS; } else { twRc = TWCC_BADVALUE; } break; default: m_twStatus.ConditionCode = TWCC_BADPROTOCOL; twRc = TWRC_FAILURE; DSError(); break; } } return twRc; }
TW_UINT16 CWiaDataSrc::OnUserInterfaceMsg(PTWAIN_MSG ptwMsg) { DBG_FN_DS(CWiaDataSrc::OnUserInterfaceMsg()); TW_UINT16 twRc = TWRC_SUCCESS;
switch (ptwMsg->MSG) { case MSG_ENABLEDS: switch (GetTWAINState()) { case DS_STATE_5: case DS_STATE_6: case DS_STATE_7: m_twStatus.ConditionCode = TWCC_SEQERROR; twRc = TWRC_FAILURE; break; default: twRc = EnableDS((TW_USERINTERFACE*)ptwMsg->pData); break; } break; case MSG_DISABLEDS: twRc = DisableDS((TW_USERINTERFACE*)ptwMsg->pData); break; default: m_twStatus.ConditionCode = TWCC_BADPROTOCOL; twRc = TWRC_FAILURE; DSError(); break; } return twRc; }
TW_UINT16 CWiaDataSrc::OnCapabilityMsg(PTWAIN_MSG ptwMsg) { DBG_FN_DS(CWiaDataSrc::OnCapabilityMsg()); TW_UINT16 twRc = TWRC_SUCCESS; TW_UINT16 twCC = TWCC_SUCCESS;
TW_CAPABILITY *ptwCap = (TW_CAPABILITY *)ptwMsg->pData; if (!ptwCap) { m_twStatus.ConditionCode = TWCC_BADCAP; return TWRC_FAILURE; } if (CAP_SUPPORTEDCAPS == ptwCap->Cap) { switch(ptwMsg->MSG) { case MSG_SET: case MSG_RESET: { //
// MSG_SET, MSG_RESET shouldn't be able to be called on CAP_SUPPORTEDCAPS!!
//
twRc = TWRC_FAILURE; m_twStatus.ConditionCode = TWCC_CAPBADOPERATION; return twRc; } default: break; }
//
// get number of PRIVATE TWAIN capabilities from WIA driver
// and add them to our CAP_SUPPORTEDCAPS list.
//
LONG lNumPrivateCaps = 0; LONG *pPrivateCapArray = NULL; lNumPrivateCaps = GetPrivateSupportedCapsFromWIADevice(&pPrivateCapArray);
ptwCap->ConType = TWON_ARRAY; ptwCap->hContainer = GlobalAlloc(GHND, sizeof(TW_ARRAY) + sizeof(TW_UINT16) * (m_NumCaps + lNumPrivateCaps) ); if (ptwCap->hContainer) { TW_ARRAY *pCapIdArray = (TW_ARRAY *) GlobalLock(ptwCap->hContainer); if (pCapIdArray) { TW_UINT32 i = 0; pCapIdArray->ItemType = TWTY_UINT16; TW_UINT16 *ItemList; ItemList = (TW_UINT16 *)pCapIdArray->ItemList;
//
// fill in TWAIN compat layer's supported CAPS first
//
for (i = 0; i < m_NumCaps; i++) { ItemList[i] = m_CapList[i].GetCapId(); }
//
// fill in WIA driver's private supported CAPS next
//
int PrivateCapIndex = 0; for(i = m_NumCaps; i < (m_NumCaps + lNumPrivateCaps);i++){ ItemList[i] = (TW_UINT16)pPrivateCapArray[PrivateCapIndex]; DBG_TRC(("(%d) Private Capability ID reported = %x",(PrivateCapIndex + 1), ItemList[i])); PrivateCapIndex++; }
//
// finally set NumItems
//
pCapIdArray->NumItems = (m_NumCaps + lNumPrivateCaps);
GlobalUnlock(ptwCap->hContainer); } else { GlobalFree(ptwCap->hContainer); ptwCap->hContainer = NULL; twRc = TWRC_FAILURE; m_twStatus.ConditionCode = TWCC_LOWMEMORY; } } else { twRc = TWRC_FAILURE; m_twStatus.ConditionCode = TWCC_LOWMEMORY; }
//
// delete Private capability array, if it was allocated
//
if(pPrivateCapArray){ GlobalFree(pPrivateCapArray); pPrivateCapArray = NULL; }
return twRc; }
CCap *pCap = FindCap(ptwCap->Cap); if (!pCap) { DBG_TRC(("Couldn't find the CCap object for CAP ID %x in TWAIN Compat layer CAP list, try WIA driver's private TWAIN cap list", ptwCap->Cap)); if (m_pDevice->TwainCapabilityPassThrough()) { return OnPrivateCapabilityMsg(ptwMsg); } else { m_twStatus.ConditionCode = TWCC_BADCAP; return TWRC_FAILURE; } } switch (ptwMsg->MSG) { case MSG_GET: if(ptwCap->Cap == ICAP_IMAGEDATASET) twCC = pCap->GetCurrent(ptwCap); else twCC = pCap->Get(ptwCap); break; case MSG_GETDEFAULT: twCC = pCap->GetDefault(ptwCap); break; case MSG_GETCURRENT: twCC = pCap->GetCurrent(ptwCap); break; case MSG_SET: switch (GetTWAINState()) { case DS_STATE_7: twCC = TWCC_SEQERROR; twRc = TWRC_FAILURE; break; default: twCC = SetCapability(pCap, ptwCap); break; } break; case MSG_RESET: switch (GetTWAINState()) { case DS_STATE_5: case DS_STATE_6: case DS_STATE_7: twCC = TWCC_SEQERROR; twRc = TWRC_FAILURE; break; default: { // ptwCap->Cap,
// ptwCap->ConType,
// ptwCap->hContainer);
twCC = pCap->Reset();
//
// According to the TWAIN spec, a MSG_RESET can be sent down meaning more than just
// RESET!!! It is stated that it can mean GET_DEFAULT/CURRENT, and RESET in a single call.
// Applications choose to ignore the value returned if they don't care, But if they
// attempt to read the value as the DEFAULT/CURRENT value...it must be set correctly in the
// container.
//
//
// fill the container with the current value, after the
// RESET call.
//
twCC = pCap->GetCurrent(ptwCap);
// ptwCap->ConType);
} break; } break; default: twCC = TWCC_BADPROTOCOL; DSError(); break; }
m_twStatus.ConditionCode = twCC;
if (TWCC_SUCCESS != twCC) { twRc = TWRC_FAILURE; } return twRc; }
TW_UINT16 CWiaDataSrc::OnPrivateCapabilityMsg(PTWAIN_MSG ptwMsg) { DBG_FN_DS(CWiaDataSrc::OnPrivateCapabilityMsg()); TW_UINT16 twRc = TWRC_FAILURE; m_twStatus.ConditionCode = TWCC_BADCAP;
if (ptwMsg) {
if (ptwMsg->MSG == MSG_SET) { TW_CAPABILITY *ptwCap = (TW_CAPABILITY *)ptwMsg->pData; if (ptwCap) { if ((NULL == ptwCap->hContainer)||(INVALID_HANDLE_VALUE == ptwCap->hContainer)) { return twRc; } } }
if (m_pCurrentIWiaItem) {
//
// Get the IWiaItemExtras Interface
//
IWiaItemExtras *pIWiaItemExtras = NULL; HRESULT hr = m_pCurrentIWiaItem->QueryInterface(IID_IWiaItemExtras,(void **)&pIWiaItemExtras); if (S_OK == hr) {
//
// we have an IWiaItemExtras Interface, so lets talk to the WIA device about
// the capability message
//
TW_CAPABILITY *ptwCap = (TW_CAPABILITY *)ptwMsg->pData; if (ptwCap) {
//
// Initialize the common header
//
TWAIN_CAPABILITY twCap; twCap.lSize = sizeof(twCap); // size of TWAIN_CAPABILITY structure
twCap.lMSG = ptwMsg->MSG; // TWAIN message
twCap.lCapID = ptwCap->Cap; // TWAIN capability ID
twCap.lConType = ptwCap->ConType; // TWAIN container type
twCap.lCC = TWCC_BADCAP; // TWAIN return code
twCap.lRC = TWRC_FAILURE; // TWAIN condition code
twCap.lDataSize= 0; // TWAIN capability data size
twCap.Data[0] = 0; // TWAIN capability data (first byte)
DBG_TRC(("== Private TWAIN_CAPABILITY data Header ==")); DBG_TRC(("twCap.lSize = %d", twCap.lSize)); DBG_TRC(("twCap.lMSG = %d", twCap.lMSG)); DBG_TRC(("twCap.lCapID = %x", twCap.lCapID)); DBG_TRC(("twCap.lConType = %d", twCap.lConType)); DBG_TRC(("twCap.lCC = %d", twCap.lCC)); DBG_TRC(("twCap.lRC = %d", twCap.lRC));
DWORD dwInDataSize = 0; DWORD dwOutDataSize = 0; DWORD dwContainerSize = 0; DWORD dwActualOutDataSize = 0;
BYTE *pInData = NULL; BYTE *pOutData = NULL; BYTE *pContainerData = NULL; TWAIN_CAPABILITY *pHeader = NULL;
//
// Depending on the Message type GET ot SET we do different things
//
//
// For a SET or RESET message, we just send the IN buffer, with an OUT buffer
// containing the header.
//
if ((ptwMsg->MSG == MSG_SET) || (ptwMsg->MSG == MSG_RESET)) {
dwContainerSize = 0;
if (ptwMsg->MSG == MSG_SET) {
//
// only check container size, when the TWAIN message is a MSG_SET
// MSG_RESET operations do not have containers attached.
//
dwContainerSize = (DWORD)GlobalSize(ptwCap->hContainer); }
dwInDataSize = dwContainerSize + sizeof(twCap); dwOutDataSize = sizeof(twCap); dwActualOutDataSize = dwOutDataSize;
twCap.lDataSize = dwContainerSize; DBG_TRC(("twCap.lDataSize = %d", twCap.lDataSize));
DBG_TRC(("== Processing MSG_SET or MSG_RESET Capability Message ==")); DBG_TRC(("dwInDataSize = %d",dwInDataSize)); DBG_TRC(("dwOutDataSize = %d",dwOutDataSize)); DBG_TRC(("dwActualOutDataSize = %d",dwActualOutDataSize)); DBG_TRC(("dwContainerSize = %d",dwContainerSize));
//
// allocate IN buffer and write TWAIN_CAPABILITY header
//
if (TWRC_SUCCESS == AllocatePrivateCapBuffer(&twCap,&pInData,dwInDataSize)) {
if (ptwMsg->MSG == MSG_SET) {
//
// copy TWAIN container data to IN buffer
//
if (TWRC_SUCCESS == CopyContainerToPrivateCapBuffer(pInData,ptwCap->hContainer)) {
//
// container data was copied to IN buffer
//
DBG_TRC(("Container data was successfully copied, we are processing a MSG_SET"));
} else {
//
// could not copy TWAIN container data into private capability IN buffer
//
DBG_ERR(("could not copy TWAIN container data into private capability IN buffer"));
if(pInData){ GlobalFree(pInData); pInData = NULL; }
return twRc; // return here, becuase we can not continue
}
} else {
//
// no container data needs to be copied
//
DBG_TRC(("No Container data was copied, because we are processing a MSG_RESET"));
}
//
// allocate OUT buffer and write TWAIN_CAPABILITY header
//
if (TWRC_SUCCESS == AllocatePrivateCapBuffer(&twCap,&pOutData,dwOutDataSize)) { hr = pIWiaItemExtras->Escape(ESC_TWAIN_CAPABILITY, pInData, dwInDataSize, pOutData, dwOutDataSize, &dwActualOutDataSize); if (S_OK == hr) { pHeader = (TWAIN_CAPABILITY*)pOutData; DBG_TRC(("== Returned TWAIN_CAPABILITY data Header from WIA device ==")); DBG_TRC(("pHeader->lSize = %d", pHeader->lSize)); DBG_TRC(("pHeader->lMSG = %d", pHeader->lMSG)); DBG_TRC(("pHeader->lCapID = %x", pHeader->lCapID)); DBG_TRC(("pHeader->lConType = %d", pHeader->lConType)); DBG_TRC(("pHeader->lCC = %d", pHeader->lCC)); DBG_TRC(("pHeader->lRC = %d", pHeader->lRC)); DBG_TRC(("pHeader->lDataSize = %d", pHeader->lDataSize));
twRc = (TW_UINT16)pHeader->lRC; m_twStatus.ConditionCode = (TW_UINT16)pHeader->lCC; } else {
//
// pIWiaItemExtras->Escape call failed,
// a failure means that we do not respond with a success to the TWAIN application
//
DBG_ERR(("pIWiaItemExtras->Escape Failed")); DBG_TRC(("Escape(code = %d, pInData = %p, dwInDataSize = %d, pOutData = %p, dwOutDataSize = %d,dwActualOutDataSize = %p)", ESC_TWAIN_CAPABILITY, pInData, dwInDataSize, pOutData, dwOutDataSize, &dwActualOutDataSize)); } } else {
//
// could not allocate memory for private capability OUT buffer
//
DBG_ERR(("could not allocate memory for private capability OUT buffer"));
}
} else {
//
// could not allocate memory for private capability IN buffer
//
DBG_ERR(("could not allocate memory for private capability IN buffer"));
} } else if ((ptwMsg->MSG == MSG_GET) || (ptwMsg->MSG == MSG_GETCURRENT) || (ptwMsg->MSG == MSG_GETDEFAULT)) {
dwContainerSize = 0; dwInDataSize = sizeof(twCap); dwOutDataSize = dwInDataSize; dwActualOutDataSize = dwInDataSize;
twCap.lDataSize = dwContainerSize; DBG_TRC(("twCap.lDataSize = %d", twCap.lDataSize));
DBG_TRC(("== Processing MSG_GET, MSG_GETCURRENT, or MSG_GETDEFAULT Capability Message ==")); DBG_TRC(("dwInDataSize = %d",dwInDataSize)); DBG_TRC(("dwOutDataSize = %d",dwOutDataSize)); DBG_TRC(("dwActualOutDataSize = %d",dwActualOutDataSize)); DBG_TRC(("dwContainerSize = %d",dwContainerSize));
//
// allocate IN buffer and write TWAIN_CAPABILITY header
//
if (TWRC_SUCCESS == AllocatePrivateCapBuffer(&twCap,&pInData,dwInDataSize)) {
//
// ask the WIA driver how large is the data, so
// we can allocate the proper OUT buffer
//
//
// allocate OUT buffer and write TWAIN_CAPABILITY header
//
if (TWRC_SUCCESS == AllocatePrivateCapBuffer(&twCap,&pOutData,dwOutDataSize)) {
hr = pIWiaItemExtras->Escape(ESC_TWAIN_CAPABILITY, pInData, dwInDataSize, pOutData, dwOutDataSize, &dwActualOutDataSize); if (S_OK == hr) {
//
// make sure that the returned data is large enough to
// contain a proper header.
//
if (dwActualOutDataSize == dwInDataSize) {
pHeader = (TWAIN_CAPABILITY*)pOutData; DBG_TRC(("== Returned TWAIN_CAPABILITY data Header from WIA device ==")); DBG_TRC(("pHeader->lSize = %d", pHeader->lSize)); DBG_TRC(("pHeader->lMSG = %d", pHeader->lMSG)); DBG_TRC(("pHeader->lCapID = %x", pHeader->lCapID)); DBG_TRC(("pHeader->lConType = %d", pHeader->lConType)); DBG_TRC(("pHeader->lCC = %d", pHeader->lCC)); DBG_TRC(("pHeader->lRC = %d", pHeader->lRC)); DBG_TRC(("pHeader->lDataSize = %d", pHeader->lDataSize));
if (pHeader->lDataSize > 0) {
//
// update common header data size from information returned
// to create OUT buffer header
//
twCap.lDataSize = pHeader->lDataSize;
//
// set new out data size to (data + header) size
//
dwOutDataSize = (pHeader->lDataSize + sizeof(twCap));
//
// update InBuffer header data size from the common header
//
pHeader = (TWAIN_CAPABILITY*)pInData; pHeader->lDataSize = twCap.lDataSize;
//
// free old out buffer, before allocating new one
//
if (pOutData) { GlobalFree(pOutData); pOutData = NULL; }
//
// allocate OUT buffer and write TWAIN_CAPABILITY header
//
if (TWRC_SUCCESS == AllocatePrivateCapBuffer(&twCap,&pOutData,dwOutDataSize)) { hr = pIWiaItemExtras->Escape(ESC_TWAIN_CAPABILITY, pInData, dwInDataSize, pOutData, dwOutDataSize, &dwActualOutDataSize); if (S_OK == hr) { pHeader = (TWAIN_CAPABILITY*)pOutData; DBG_TRC(("== Returned TWAIN_CAPABILITY data Header from WIA device ==")); DBG_TRC(("pHeader->lSize = %d", pHeader->lSize)); DBG_TRC(("pHeader->lMSG = %d", pHeader->lMSG)); DBG_TRC(("pHeader->lCapID = %x", pHeader->lCapID)); DBG_TRC(("pHeader->lConType = %d", pHeader->lConType)); DBG_TRC(("pHeader->lCC = %d", pHeader->lCC)); DBG_TRC(("pHeader->lRC = %d", pHeader->lRC)); DBG_TRC(("pHeader->lDataSize = %d", pHeader->lDataSize)); twRc = (TW_UINT16)pHeader->lRC; m_twStatus.ConditionCode = (TW_UINT16)pHeader->lCC; if (TWRC_SUCCESS == twRc) { if (TWRC_SUCCESS == CopyPrivateCapBufferToContainer(&ptwCap->hContainer,pOutData,pHeader->lDataSize)) { ptwCap->ConType = (TW_UINT16)pHeader->lConType; } else {
//
// could not copy private capability buffer into TWAIN container data
//
DBG_ERR(("could not copy private capability buffer into TWAIN container data"));
} } else {
//
// WIA driver failed the TWAIN capability request, by returning a TWAIN failure
// return code in the OUT header.
//
DBG_ERR(("WIA driver failed the TWAIN capability request, by returning a TWAIN failure return code in the OUT header."));
} } else {
//
// pIWiaItemExtras->Escape call failed, (sending passthrough operation)
// a failure means that we do not respond with a success to the TWAIN application
//
DBG_ERR(("pIWiaItemExtras->Escape Failed (sending passthrough operation)")); DBG_TRC(("Escape(code = %d, pInData = %p, dwInDataSize = %d, pOutData = %p, dwOutDataSize = %d,dwActualOutDataSize = %d)", ESC_TWAIN_CAPABILITY, pInData, dwInDataSize, pOutData, dwOutDataSize, dwActualOutDataSize));
} } else {
//
// could not allocate memory for private capability OUT buffer
//
DBG_ERR(("could not allocate memory for private capability OUT buffer"));
} } else {
//
// OUT buffer size returned from the WIA driver is too small to contain a
// proper header.
//
DBG_ERR(("OUT buffer size (%d) returned from the WIA driver is too small to contain data",pHeader->lDataSize));
} } else {
//
// OUT buffer size returned from the WIA driver is too small to contain a
// proper header.
//
DBG_ERR(("OUT buffer size (%d) returned from the WIA driver is too small to contain a proper header",dwActualOutDataSize));
} } else {
//
// pIWiaItemExtras->Escape call failed, (requesting OUT buffer size)
// a failure means that we do not respond with a success to the TWAIN application
//
DBG_ERR(("pIWiaItemExtras->Escape Failed (requesting OUT buffer size)")); DBG_TRC(("Escape(code = %d, pInData = %p, dwInDataSize = %d, pOutData = %p, dwOutDataSize = %d,dwActualOutDataSize = %d)", ESC_TWAIN_CAPABILITY, pInData, dwInDataSize, pInData, dwInDataSize, dwActualOutDataSize)); } } else {
//
// could not allocate memory for private capability OUT buffer
//
DBG_ERR(("could not allocate memory for private capability OUT buffer"));
} } else {
//
// could not allocate memory for private capability IN buffer
//
DBG_ERR(("could not allocate memory for private capability IN buffer"));
} }
//
// free IN buffer
//
if (pInData) { GlobalFree(pInData); pInData = NULL; }
//
// free OUT buffer
//
if (pOutData) { GlobalFree(pOutData); pOutData = NULL; } } else {
//
// could not get TWAIN capability from TWAIN message
//
DBG_ERR(("could not get TWAIN capability from TWAIN message")); }
//
// release IWiaItemExtras Interface
//
if (pIWiaItemExtras) { pIWiaItemExtras->Release(); pIWiaItemExtras = NULL; } } else {
//
// QI for IWiaItemExtras Failed
//
DBG_ERR(("QueryInterface for IWiaItemExtras Failed"));
} } else {
//
// no current item selected
//
DBG_ERR(("no current item selected for use"));
} } else {
//
// imcoming TWAIN capability is NULL
//
DBG_ERR(("incoming TWAIN capability is NULL"));
} return twRc; }
TW_UINT16 CWiaDataSrc::AllocatePrivateCapBuffer(TWAIN_CAPABILITY *pHeader, BYTE** ppBuffer, DWORD dwSize) { DBG_FN_DS(CWiaDataSrc::AllocatePrivateCapBuffer()); if(dwSize < sizeof(TWAIN_CAPABILITY) || (!ppBuffer)|| (!pHeader)){ return TWRC_FAILURE; }
*ppBuffer = (BYTE*)GlobalAlloc(GPTR,dwSize); if(*ppBuffer){ memcpy(*ppBuffer, pHeader,sizeof(TWAIN_CAPABILITY)); } else { return TWRC_FAILURE; }
return TWRC_SUCCESS; }
TW_UINT16 CWiaDataSrc::CopyContainerToPrivateCapBuffer(BYTE* pBuffer, HGLOBAL hContainer) { DBG_FN_DS(CWiaDataSrc::CopyContainerToPrivateCapBuffer()); if((!pBuffer)||(!hContainer)){ return TWRC_FAILURE; }
DWORD dwContainerSize = (DWORD)GlobalSize(hContainer); BYTE *pContainerBuffer = (BYTE*)GlobalLock(hContainer); if(!pContainerBuffer){ return TWRC_FAILURE; }
TWAIN_CAPABILITY *pHeader = (TWAIN_CAPABILITY*)pBuffer; memcpy((BYTE*)pHeader->Data,pContainerBuffer,dwContainerSize);
//
// unlock handle before returning
//
GlobalUnlock(hContainer);
return TWRC_SUCCESS; }
TW_UINT16 CWiaDataSrc::CopyPrivateCapBufferToContainer(HGLOBAL *phContainer, BYTE* pBuffer, DWORD dwSize) { DBG_FN_DS(CWiaDataSrc::CopyPrivateCapBufferToContainer()); if((!phContainer) || (!pBuffer) || (dwSize <= 0)){ return TWRC_FAILURE; }
*phContainer = NULL; *phContainer = (HGLOBAL)GlobalAlloc(GHND,dwSize); if(!*phContainer){ return TWRC_FAILURE; }
BYTE *pContainerBuffer = (BYTE*)GlobalLock(*phContainer); if(!pContainerBuffer){ GlobalFree(*phContainer); *phContainer = NULL; return TWRC_FAILURE; }
TWAIN_CAPABILITY *pHeader = (TWAIN_CAPABILITY*)pBuffer;
memcpy(pContainerBuffer,(BYTE*)pHeader->Data,dwSize);
//
// unlock handle before returning
//
GlobalUnlock(*phContainer);
return TWRC_SUCCESS; }
TW_UINT16 CWiaDataSrc::SetCapability(CCap *pCap,TW_CAPABILITY *ptwCap) { DBG_FN_DS(CWiaDataSrc::SetCapability()); if (!pCap || !ptwCap) { m_twStatus.ConditionCode = TWCC_BADCAP; return TWRC_FAILURE; }
return pCap->Set(ptwCap); }
TW_UINT16 CWiaDataSrc::OnStatusMsg(PTWAIN_MSG ptwMsg) { DBG_FN_DS(CWiaDataSrc::OnStatusMsg()); TW_UINT16 twRc = TWRC_SUCCESS;
if (MSG_GET == ptwMsg->MSG) { *((TW_STATUS*)ptwMsg->pData) = m_twStatus; twRc = TWRC_SUCCESS; } else { twRc = TWRC_FAILURE; m_twStatus.ConditionCode = TWCC_BADPROTOCOL; DSError(); } return twRc; }
TW_UINT16 CWiaDataSrc::OnPendingXfersMsg(PTWAIN_MSG ptwMsg) { m_twStatus.ConditionCode = TWCC_BUMMER; return TWRC_FAILURE; }
TW_UINT16 CWiaDataSrc::OnImageMemXferMsg(PTWAIN_MSG ptwMsg) { DBG_FN_DS(CWiaDataSrc::OnImageMemXferMsg()); TW_UINT16 twRc = TWRC_SUCCESS; HRESULT hr = E_FAIL; switch (GetTWAINState()) { case DS_STATE_6: case DS_STATE_7: { if (MSG_GET == ptwMsg->MSG) { TW_IMAGEMEMXFER *pMemXfer = (TW_IMAGEMEMXFER *)ptwMsg->pData;
if ((m_hMemXferBits == NULL)) {
m_LinesTransferred = 0;
GUID guidFormat = GUID_NULL;
DBG_WRN(("Transferring %d bit data",m_MemoryTransferInfo.mtiBitsPerPixel)); if (m_MemoryTransferInfo.mtiBitsPerPixel > 32) {
//
// Load image into memory for memory transfer (hi-color images)
//
guidFormat = WiaImgFmt_RAWRGB; } else {
//
// The TWAIN compatibility layer has the ability to transfer images
// 1,2,4,8,16,24 and 32 bit when using MEMORYBMP.
//
guidFormat = WiaImgFmt_MEMORYBMP; }
twRc = TransferToMemory(guidFormat);
if (TWRC_SUCCESS != twRc) { return twRc; } else {
//
// transition to STATE_7
//
SetTWAINState(DS_STATE_7); } }
//
// turn off the Image caching flag
//
m_bCacheImage = FALSE;
//
// Lock down the memory and get the address to the bits
//
GetMemoryTransferBits((BYTE*)GlobalLock(m_hMemXferBits));
m_pMemXferBits = m_MemoryTransferInfo.mtipBits;
if (m_pMemXferBits) { if(m_MemoryTransferInfo.mtiHeightPixels == 0){ m_MemoryTransferInfo.mtiHeightPixels = m_ImageHeight; }
if(m_MemoryTransferInfo.mtiguidFormat == WiaImgFmt_MEMORYBMP){
//
// adjust the image information to report the actual information
// reported in the BITMAPINFO header.
//
//
// only change these values, if the current information does not
// match the image header. (always take the header's values)
//
if(m_MemoryTransferInfo.mtiHeightPixels != m_ImageHeight){ m_MemoryTransferInfo.mtiHeightPixels = m_ImageHeight; }
if(m_MemoryTransferInfo.mtiWidthPixels != m_ImageWidth){ m_MemoryTransferInfo.mtiWidthPixels = m_ImageWidth; }
}
DBG_TRC(("CWiaDataSrc::OnImageMemXferMsg(), Transferring (%d) of (%d) total lines of image data.",m_LinesTransferred,m_MemoryTransferInfo.mtiHeightPixels)); if (m_LinesTransferred >= (TW_UINT32)m_MemoryTransferInfo.mtiHeightPixels) {
//
// we have completed the transfer, or we are out
// of scan lines to copy..so return XFERDONE
//
//
// unlock memory before bailing
//
// Keep unlock and NULLing together
GlobalUnlock(m_hMemXferBits); m_pMemXferBits = NULL;
ResetMemXfer(); m_twStatus.ConditionCode = TWCC_SUCCESS;
return TWRC_XFERDONE; } else {
//
// looks like we are working with transfer data
//
BYTE * pAppBuffer = NULL; if (pMemXfer->Memory.Flags & TWMF_HANDLE) {
DBG_TRC(("TWAIN Application wants to work with a HANDLE"));
//
// if the memory is a HANDLE, lock it first
//
pAppBuffer = (LPBYTE)GlobalLock(pMemXfer->Memory.TheMem); } else if (pMemXfer->Memory.Flags & TWMF_POINTER) {
DBG_TRC(("TWAIN Application wants to work with a POINTER"));
//
// if the memory is a POINTER, then proceed
//
pAppBuffer = (LPBYTE)pMemXfer->Memory.TheMem; } else {
DBG_TRC(("TWAIN Application gave us nothing to work with"));
//
// we have no memory, so set it to NULL
//
pAppBuffer = NULL; }
//
// if (there is no Memory to write to), or
// (the app doesn't own the memory), or
// (the length is less than MIN_ ), or
// (the length is greater than MAX),
// return a FAILURE!, and a CC of BADVALUE
//
if (!pAppBuffer || !(pMemXfer->Memory.Flags & TWMF_APPOWNS) || pMemXfer->Memory.Length < MIN_MEMXFER_SIZE || pMemXfer->Memory.Length > MAX_MEMXFER_SIZE) {
twRc = TWRC_FAILURE; m_twStatus.ConditionCode = TWCC_BADVALUE;
} else {
//
// set memory Xfer values
//
UINT ScanlinesToCopy = 0; pMemXfer->BytesPerRow = GetLineSize(&m_MemoryTransferInfo); ScanlinesToCopy = min(pMemXfer->Memory.Length / pMemXfer->BytesPerRow, (TW_UINT32)(m_MemoryTransferInfo.mtiHeightPixels - m_LinesTransferred));
pMemXfer->Compression = TWCP_NONE; pMemXfer->Columns = m_MemoryTransferInfo.mtiWidthPixels; pMemXfer->Rows = ScanlinesToCopy; pMemXfer->XOffset = 0; pMemXfer->YOffset = m_LinesTransferred; pMemXfer->BytesWritten = pMemXfer->BytesPerRow * ScanlinesToCopy;
#ifdef DEBUG_MEMXFER
DBG_TRC(("CWiaDataSrc::OnImageMemXferMsg(), Reports TW_IMAGEMEMXFER")); DBG_TRC(("pMemXfer->Compression = %d",pMemXfer->Compression)); DBG_TRC(("pMemXfer->Columns = %d",pMemXfer->Columns)); DBG_TRC(("pMemXfer->Rows = %d",pMemXfer->Rows)); DBG_TRC(("pMemXfer->XOffset = %d",pMemXfer->XOffset)); DBG_TRC(("pMemXfer->YOffset = %d",pMemXfer->YOffset)); DBG_TRC(("pMemXfer->BytesPerRow = %d",pMemXfer->BytesPerRow)); DBG_TRC(("pMemXfer->BytesWritten = %d",pMemXfer->BytesWritten)); DBG_TRC(("pAppBuffer = %p, m_pMemXferBits = %p",pAppBuffer,m_pMemXferBits)); #endif
//
// Transfer one-line strips in a loop to Application supplied buffer
//
LPBYTE pTo = pAppBuffer; LPBYTE pFrom = m_pMemXferBits + m_LinesTransferred * GetLineSize(&m_MemoryTransferInfo); for (UINT i=0;i < ScanlinesToCopy;i++ ) {
//
// swap color values, if needed
//
if (m_MemoryTransferInfo.mtiBitsPerPixel == 24) { for (ULONG ulIndex = 0; ulIndex < pMemXfer->BytesPerRow; ulIndex+= 3) {
// 1 2 3
// RED-GREEN-BLUE
//
BYTE bFirst = pFrom[ulIndex]; pFrom[ulIndex] = pFrom[ulIndex+2]; pFrom[ulIndex+2] = bFirst; } }
/*
if(m_MemoryTransferInfo.mtiBitsPerPixel == 48){ for(j = 0; j < pMemXfer->BytesPerRow; j+=6){
// 1 2 1 2 1 2
// REDRED-GREENGREEN-BLUEBLUE
//
BYTE bFirst = pFrom[j]; BYTE bSecond = pFrom[j+1]; pFrom[j] = pFrom[j+4]; pFrom[j+1] = pFrom[j+5]; pFrom[j+4] = bFirst; pFrom[j+5] = bSecond; } } */
//
// copy line to application supplied buffer
//
memcpy(pTo,pFrom,pMemXfer->BytesPerRow); pFrom+=GetLineSize(&m_MemoryTransferInfo); pTo+=pMemXfer->BytesPerRow; }
//
// calculate lines transferred
//
m_LinesTransferred += ScanlinesToCopy; if (m_LinesTransferred >= (TW_UINT32)m_MemoryTransferInfo.mtiHeightPixels) {
//
// we have completed the transfer, or we are out
// of scan lines to copy..so return XFERDONE
//
twRc = TWRC_XFERDONE; m_twStatus.ConditionCode = TWCC_SUCCESS;
// Keep unlock and NULLing together
GlobalUnlock(m_hMemXferBits); m_pMemXferBits = NULL;
ResetMemXfer();
//
// if we are working with an application provided HANDLE,
// GlobalUnlock it before continuing
//
if (pMemXfer->Memory.Flags & TWMF_HANDLE) { GlobalUnlock(pMemXfer->Memory.TheMem); }
return twRc; }
//
// if we are working with an application provided HANDLE,
// GlobalUnlock it before continuing
//
if (pMemXfer->Memory.Flags & TWMF_HANDLE) { GlobalUnlock(pMemXfer->Memory.TheMem); } } }
//
// unlock buffer when finished
//
// Keep unlock and NULLing together
GlobalUnlock(m_hMemXferBits); m_pMemXferBits = NULL;
} else {
//
// Could not lock down memory for transfer
//
m_twStatus.ConditionCode = TWCC_LOWMEMORY; return TWRC_FAILURE; }
} else {
//
// we recieved a message other than the expected MSG_GET
//
twRc = TWRC_FAILURE; m_twStatus.ConditionCode = TWCC_BADPROTOCOL; } } break; default: { twRc = TWRC_FAILURE; m_twStatus.ConditionCode = TWCC_SEQERROR; return twRc; break; } break; }
//
// if we failed, report it properly
//
if (TWRC_FAILURE == twRc) DSError();
return twRc; }
TW_UINT16 CWiaDataSrc::OnImageFileXferMsg(PTWAIN_MSG ptwMsg) { DBG_FN_DS(CWiaDataSrc::OnImageFileXferMsg()); TW_UINT16 twRc = TWRC_SUCCESS;
if (MSG_GET == ptwMsg->MSG) { GUID guidFileFormat = WiaImgFmt_BMP;
CCap *pCap = FindCap(ICAP_IMAGEFILEFORMAT); if(pCap){ guidFileFormat = ICAP_IMAGEFILEFORMAT_TO_WIA_IPA_FORMAT((TW_UINT16)pCap->GetCurrent()); }
twRc = TransferToFile(guidFileFormat); if(TWRC_XFERDONE == twRc) { SetTWAINState(DS_STATE_7); } else { DBG_ERR(("CWiaDataSrc::OnImageFileXferMsg(), TransferToFile() failed")); } } else { twRc = TWRC_FAILURE; m_twStatus.ConditionCode = TWCC_BADPROTOCOL; }
if (TWRC_FAILURE == twRc){ DSError(); }
return twRc; }
TW_UINT16 CWiaDataSrc::OnImageNativeXferMsg(PTWAIN_MSG ptwMsg) { DBG_FN_DS(CWiaDataSrc::OnImageNativeXferMsg()); TW_UINT16 twRc = TWRC_SUCCESS;
HGLOBAL hDIB = NULL;
switch (GetTWAINState()) { case DS_STATE_6: { if (MSG_GET == ptwMsg->MSG) { twRc = TransferToDIB(&hDIB); if (TWRC_XFERDONE == twRc) { SetTWAINState(DS_STATE_7); *(TW_UINT32*)ptwMsg->pData = (TW_UINT32)(INT_PTR)hDIB; } else { DBG_ERR(("CWiaDataSrc::OnImageNativeXferMsg(), TransferToDIB() failed")); } } else { twRc = TWRC_FAILURE; m_twStatus.ConditionCode = TWCC_BADPROTOCOL; } } break; default: twRc = TWRC_FAILURE; m_twStatus.ConditionCode = TWCC_SEQERROR; break; }
if (TWRC_FAILURE == twRc){ DSError(); } return twRc; }
TW_UINT16 CWiaDataSrc::OpenDS(PTWAIN_MSG ptwMsg) { DBG_FN_DS(CWiaDataSrc::OpenDS()); TW_UINT16 twRc = TWRC_SUCCESS;
if (DS_STATE_3 == GetTWAINState()) { //
// No multiple clients are allowed.
// This is enforced by making sure that our identity's id field
// has a value of 0.
if (m_dsIdentity.Id) {
m_twStatus.ConditionCode = TWCC_MAXCONNECTIONS; twRc = TWRC_FAILURE; } else { //
// make a copy of the caller's identity
//
m_AppIdentity = *ptwMsg->AppId; m_dsIdentity = *((TW_IDENTITY *)ptwMsg->pData); HRESULT hr = S_OK; hr = m_pDevice->Open(CWiaDataSrc::DeviceEventCallback, (LPARAM)this); if (FAILED(hr)) { twRc = TWRC_FAILURE; m_twStatus.ConditionCode = TWCC_BUMMER; } } } else { m_twStatus.ConditionCode = TWCC_SEQERROR; twRc = TWRC_FAILURE; }
if (TWRC_SUCCESS == twRc) {
//
// transition to STATE_4
//
SetTWAINState(DS_STATE_4); }
if (TWRC_SUCCESS != twRc) { } return twRc; }
TW_UINT16 CWiaDataSrc::CloseDS(PTWAIN_MSG ptwMsg) { DBG_FN_DS(CWiaDataSrc::CloseDS()); TW_UINT16 twRc = TWRC_SUCCESS;
switch (GetTWAINState()) { case DS_STATE_7: case DS_STATE_6: case DS_STATE_5: case DS_STATE_4: m_pDevice->Close(); //DBG_TRC(("Calling ResetMemXfer because CLOSEDS was called"));
ResetMemXfer(); //
// We are up for sale again.
//
m_AppIdentity.Id = 0;
//
// transition to STATE_3
//
SetTWAINState(DS_STATE_3);
if (m_pIWiaItems) delete [] m_pIWiaItems; m_pIWiaItems = NULL; m_NumIWiaItems = 0; m_NextIWiaItemIndex = 0; break; default: m_twStatus.ConditionCode = TWCC_SEQERROR; twRc = TWRC_FAILURE; DSError(); break; } return twRc; }
TW_UINT16 CWiaDataSrc::EnableDS(TW_USERINTERFACE *pUI) { return TWRC_FAILURE; }
TW_UINT16 CWiaDataSrc::DisableDS(TW_USERINTERFACE *pUI) { DBG_FN_DS(CWiaDataSrc::DisableDS()); TW_UINT16 twRc = TWRC_SUCCESS; switch (GetTWAINState()) { case DS_STATE_5:
//
// transition to STATE_4
//
SetTWAINState(DS_STATE_4); break; default: twRc = TWRC_FAILURE; m_twStatus.ConditionCode = TWCC_SEQERROR; DSError(); break; } return twRc; }
TW_UINT16 CWiaDataSrc::CreateCapList(TW_UINT32 NumCaps,PCAPDATA pCapData) { DBG_FN_DS(CWiaDataSrc::CreateCapList()); if (!NumCaps || !pCapData) return TWCC_BADVALUE;
TW_UINT16 twCc = TWCC_SUCCESS;
DestroyCapList(); m_CapList = new CCap[NumCaps]; if (m_CapList) {
for (m_NumCaps = 0; m_NumCaps < NumCaps; m_NumCaps++) { twCc = m_CapList[m_NumCaps].ICap(&pCapData[m_NumCaps]); if (TWCC_SUCCESS != twCc) { break; } } m_NumCaps = NumCaps;
} else { twCc = TWCC_LOWMEMORY; }
if (TWCC_SUCCESS != twCc && m_CapList) { DestroyCapList(); }
return twCc; }
TW_UINT16 CWiaDataSrc::DestroyCapList() { DBG_FN_DS(CWiaDataSrc::DestroyCapList()); if (m_CapList) { delete [] m_CapList; m_CapList = NULL; } m_NumCaps = 0; return TWCC_SUCCESS; }
CCap * CWiaDataSrc::FindCap(TW_UINT16 CapId) { TW_UINT32 ui32; for (ui32 = 0; ui32 < m_NumCaps; ui32++) { if (m_CapList[ui32].GetCapId() == CapId) return &m_CapList[ui32]; } return NULL; }
void CWiaDataSrc::DSError() { DBG_FN_DS(CWiaDataSrc::DSError()); NotifyCloseReq(); }
HRESULT CALLBACK CWiaDataSrc::DeviceEventCallback(LONG lEvent,LPARAM lParam) { CWiaDataSrc *pDataSrc = NULL; pDataSrc = (CWiaDataSrc *)lParam; if (pDataSrc) { pDataSrc->NotifyCloseReq(); return S_OK; } return E_FAIL; }
DS_STATE CWiaDataSrc::SetTWAINState(DS_STATE NewTWAINState) { DBG_TRC(("(Transitioning From TWAIN STATE %d to TWAIN STATE %d)",m_dsState,NewTWAINState)); m_dsState = NewTWAINState; return m_dsState; }
DS_STATE CWiaDataSrc::GetTWAINState() { return m_dsState; }
TW_UINT16 CWiaDataSrc::SetStatusTWCC(TW_UINT16 NewConditionCode) { m_twStatus.ConditionCode = NewConditionCode; return NewConditionCode; }
float CWiaDataSrc::ConvertToTWAINUnits(LONG lValue, LONG lResolution) { float fReturnValue = 0.0f; CCap *pUnits = FindCap(ICAP_UNITS); if(pUnits){ switch (pUnits->GetCurrent()) { case TWUN_INCHES: fReturnValue = (float)lValue / (float)lResolution; break; case TWUN_CENTIMETERS: fReturnValue = (float)((lValue * 2.54) / (float)lResolution); break; case TWUN_PICAS: fReturnValue = (float)((lValue * 6.00) / (float)lResolution); break; case TWUN_POINTS: fReturnValue = (float)(((float)lValue * 72.0) / (float)lResolution); break; case TWUN_PIXELS: default: fReturnValue = (float)lValue; break; } } return fReturnValue; }
LONG CWiaDataSrc::ConvertFromTWAINUnits(float fValue, LONG lResolution) { LONG lReturnValue = 0; CCap *pUnits = FindCap(ICAP_UNITS); if (pUnits) { switch (pUnits->GetCurrent()) { case TWUN_INCHES: lReturnValue = (LONG)((float)fValue * (float)lResolution); break; case TWUN_CENTIMETERS: lReturnValue = (LONG)(((float)fValue / 2.54) * (float)lResolution); break; case TWUN_PICAS: lReturnValue = (LONG)(((float)fValue / 6.00) * (float)lResolution); break; case TWUN_POINTS: lReturnValue = (LONG)(((float)fValue / 72.0) * (float)lResolution); break; case TWUN_PIXELS: default: lReturnValue = (LONG)fValue; break; } } return lReturnValue; }
DWORD CWiaDataSrc::ReadTwainRegistryDWORDValue(LPTSTR szRegValue, DWORD dwDefault) { DBG_FN_DS(CWiaDataSrc::ReadTwainRegistryDWORDValue()); DWORD dwValue = 0; DWORD dwType = REG_DWORD; DWORD dwDataSize = sizeof(DWORD); DWORD dwDisposition = REG_OPENED_EXISTING_KEY; HKEY hTwainRootKey = NULL; if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_USER,TWAIN_REG_KEY,0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS, NULL,&hTwainRootKey,&dwDisposition)){
if(dwDisposition == REG_CREATED_NEW_KEY){ DBG_WRN(("CWiaDataSrc::ReadTwainRegistryDWORDValue(), Created Root Twain Registry Key")); }
if (ERROR_SUCCESS == RegQueryValueEx(hTwainRootKey,szRegValue,NULL,&dwType,(BYTE*)&dwValue,&dwDataSize)) { #ifdef UNICODE
DBG_TRC(("CWiaDataSrc::ReadTwainRegistryDWORDValue(), Reading %ws Registry Key Value = %d",szRegValue,dwValue)); #else
DBG_TRC(("CWiaDataSrc::ReadTwainRegistryDWORDValue(), Reading %s Registry Key Value = %d",szRegValue,dwValue)); #endif
} else { // reset sizes, just for safety
dwType = REG_DWORD; dwDataSize = sizeof(DWORD); dwValue = dwDefault; if(ERROR_SUCCESS == RegSetValueEx(hTwainRootKey,szRegValue,NULL,dwType,(BYTE*)&dwDefault,dwDataSize)){ #ifdef UNICODE
DBG_TRC(("CWiaDataSrc::ReadTwainRegistryDWORDValue(), Writing Default Value for %ws Registry Key Value = %d",szRegValue,dwDefault)); #else
DBG_TRC(("CWiaDataSrc::ReadTwainRegistryDWORDValue(), Writing Default Value for %s Registry Key Value = %d",szRegValue,dwDefault)); #endif
} else { #ifdef UNICODE
DBG_TRC(("CWiaDataSrc::ReadTwainRegistryDWORDValue(), Error Reading %ws Registry Key Value",szRegValue)); #else
DBG_TRC(("CWiaDataSrc::ReadTwainRegistryDWORDValue(), Error Reading %s Registry Key Value",szRegValue)); #endif
} }
RegCloseKey(hTwainRootKey); hTwainRootKey = NULL; } else { DBG_ERR(("CWiaDataSrc::ReadTwainRegistryDWORDValue(), could not open Root TWAIN Registry Key")); } return dwValue; }
LONG CWiaDataSrc::GetPrivateSupportedCapsFromWIADevice(LONG **ppCapArray) { DBG_FN_DS(CWiaDataSrc::GetPrivateSupportedCapsFromWIADevice()); if (!ppCapArray) { DBG_ERR(("CWiaDataSrc::GetPrivateSupportedCapsFromWIADevice(), ppCapArray is NULL")); return 0; }
*ppCapArray = NULL; LONG lNumPrivateCaps = 0; if (m_pDevice) { if (m_pDevice->TwainCapabilityPassThrough()) { if (m_pCurrentIWiaItem) {
//
// Get the IWiaItemExtras Interface
//
IWiaItemExtras *pIWiaItemExtras = NULL; HRESULT hr = m_pCurrentIWiaItem->QueryInterface(IID_IWiaItemExtras,(void **)&pIWiaItemExtras); if (S_OK == hr) {
//
// set data sizes
//
DWORD dwInDataSize = 0; DWORD dwOutDataSize = 0; DWORD dwActualOutDataSize = 0;
BYTE *pInData = NULL; BYTE *pOutData = NULL;
LONG lCapabilityDataSize = sizeof(LONG); pOutData = (BYTE*)&lCapabilityDataSize; pInData = (BYTE*)&lCapabilityDataSize;
dwActualOutDataSize = sizeof(LONG); dwInDataSize = dwActualOutDataSize; dwOutDataSize = dwActualOutDataSize;
//
// ask how many bytes are needed to store the private TWAIN capabilities the WIA driver supports
//
hr = pIWiaItemExtras->Escape(ESC_TWAIN_PRIVATE_SUPPORTED_CAPS, pInData, dwInDataSize, pOutData, dwOutDataSize, &dwActualOutDataSize); if (S_OK == hr) {
lCapabilityDataSize = (LONG)(*pOutData);
lNumPrivateCaps = (lCapabilityDataSize / sizeof(LONG));
DBG_TRC(("WIA device reported %d private TWAIN supported CAPS",lNumPrivateCaps));
if (lNumPrivateCaps > 0) {
//
// allocate an array of LONGs for the WIA driver to fill with
// CAP ids.
//
dwOutDataSize = (lCapabilityDataSize + PRIVATE_CAP_ARRAY_PADDING); dwActualOutDataSize = dwOutDataSize;
*ppCapArray = (LONG*)GlobalAlloc(GPTR,dwOutDataSize); if (*ppCapArray) {
pOutData = (BYTE*)*ppCapArray;
//
// ask the WIA driver to fill the array of LONGS
//
hr = pIWiaItemExtras->Escape(ESC_TWAIN_PRIVATE_SUPPORTED_CAPS, pInData, dwInDataSize, pOutData, dwOutDataSize, &dwActualOutDataSize); if (FAILED(hr)) {
//
// pIWiaItemExtras->Escape call failed,
// a failure means that there are no private supported capabilities
//
DBG_ERR(("pIWiaItemExtras->Escape Failed (sending a request for the cability array data)")); DBG_TRC(("Escape(code = %d, pInData = %p, dwInDataSize = %d, pOutData = %p, dwOutDataSize = %d,dwActualOutDataSize = %d)", ESC_TWAIN_PRIVATE_SUPPORTED_CAPS, pInData, dwInDataSize, pOutData, dwOutDataSize, dwActualOutDataSize)); } } else { DBG_ERR(("could not allocate memory for private capability array of %d items (%d bytes - this includes padding)",lNumPrivateCaps,dwOutDataSize)); lNumPrivateCaps = 0; *ppCapArray = NULL; } } else {
//
// no supported caps
//
DBG_TRC(("No private supported caps reported from WIA device"));
}
} else {
//
// pIWiaItemExtras->Escape call failed,
// a failure means that there are no private supported capabilities
//
DBG_ERR(("pIWiaItemExtras->Escape Failed (sending a request for the number of capabilities)")); DBG_TRC(("Escape(code = %d, pInData = %p, dwInDataSize = %d, pOutData = %p, dwOutDataSize = %d,dwActualOutDataSize = %d)", ESC_TWAIN_PRIVATE_SUPPORTED_CAPS, pInData, dwInDataSize, pOutData, dwOutDataSize, dwActualOutDataSize)); }
//
// release IWiaItemExtras Interface
//
if (pIWiaItemExtras) { pIWiaItemExtras->Release(); pIWiaItemExtras = NULL; } } else {
//
// QI for IWiaItemExtras Failed
//
DBG_ERR(("QueryInterface for IWiaItemExtras Failed"));
} } else {
//
// no current item selected
//
DBG_ERR(("no current item selected for use"));
} } } else {
//
// m_pDevice is NULL
//
DBG_ERR(("CWiaDataSrc::GetPrivateSupportedCapsFromWIADevice(), m_pDevice is NULL")); } return lNumPrivateCaps; }
TW_UINT16 CWiaDataSrc::TransferToFile(GUID guidFormatID) { DBG_FN_DS(CWiaDataSrc::TransferToFile()); TW_UINT16 twRc = TWRC_FAILURE; HRESULT hr = E_FAIL;
CWiaDataCallback DataCallback; CCap *pCap = NULL; pCap = FindCap(CAP_INDICATORS); if(pCap){ DataCallback.Initialize(NULL,pCap->GetCurrent()); } else { DataCallback.Initialize(NULL,TRUE); }
IWiaDataCallback *pIDataCB = NULL; hr = DataCallback.QueryInterface(IID_IWiaDataCallback,(void **)&pIDataCB); if (SUCCEEDED(hr)) { hr = m_pDevice->LoadImageToDisk(m_pCurrentIWiaItem, m_FileXferName, guidFormatID, pIDataCB); if (SUCCEEDED(hr)) { twRc = TWRC_XFERDONE; m_twStatus.ConditionCode = TWCC_SUCCESS; } pIDataCB->Release(); pIDataCB = NULL; }
//
// check for a cancel, or out-of-paper error (scanners could return this)
//
if ((S_FALSE == hr) || (WIA_ERROR_PAPER_EMPTY == hr)) { m_twStatus.ConditionCode = TWCC_SUCCESS;
if(WIA_ERROR_PAPER_EMPTY == hr) { DBG_TRC(("CWiaDataSrc::TransferToFile(), WIA_ERROR_PAPER_EMPTY returned from source.")); }
//
// set XFERCOUNT
//
CCap *pxferCap = FindCap(CAP_XFERCOUNT); if (pxferCap) { pxferCap->SetCurrent((TW_UINT32)0); }
//
// return a cancel to abort the transfer.
// Applications will most commonly delete the current
// image, and keep the previous images.
//
twRc = TWRC_CANCEL; } else if (FAILED(hr)) { m_twStatus.ConditionCode = TWCC_FROM_HRESULT(hr); twRc = TWRC_FAILURE; }
return twRc; }
TW_UINT16 CWiaDataSrc::TransferToDIB(HGLOBAL *phDIB) { DBG_FN_DS(CWiaDataSrc::TransferToDIB()); TW_UINT16 twRc = TWRC_FAILURE; HRESULT hr = E_FAIL;
CWiaDataCallback DataCallback; CCap *pCap = NULL; pCap = FindCap(CAP_INDICATORS); if(pCap){ DataCallback.Initialize(NULL,pCap->GetCurrent()); } else { DataCallback.Initialize(NULL,TRUE); }
IWiaDataCallback *pIDataCB = NULL; hr = DataCallback.QueryInterface(IID_IWiaDataCallback,(void **)&pIDataCB); if (SUCCEEDED(hr)) { hr = m_pDevice->LoadImage(m_pCurrentIWiaItem, WiaImgFmt_MEMORYBMP, pIDataCB); // memory bmp only
if (SUCCEEDED(hr)) { if(SUCCEEDED(DataCallback.GetImage(phDIB, NULL))){
//
// DIB data (special case) - NATIVE TWAIN transfers are in DIB format always
// If we are acquiring DIB data, then we have to apply the
// height rules:
// positive = image is right side up
// negative = image is up side down
// zero = image has an unknown length (and assumed to be upside down)
if(FlipDIB(*phDIB)){ twRc = TWRC_XFERDONE; m_ImageHeight = (TW_UINT32)DataCallback.GetImageHeight(); m_ImageWidth = (TW_UINT32)DataCallback.GetImageWidth(); } } } pIDataCB->Release(); pIDataCB = NULL; }
//
// check for a cancel, or out-of-paper error (scanners could return this)
//
if ((S_FALSE == hr) || (WIA_ERROR_PAPER_EMPTY == hr)) { m_twStatus.ConditionCode = TWCC_SUCCESS;
if(WIA_ERROR_PAPER_EMPTY == hr) { DBG_TRC(("CWiaDataSrc::TransferToDIB(), WIA_ERROR_PAPER_EMPTY returned from source.")); }
//
// set XFERCOUNT
//
CCap *pxferCap = FindCap(CAP_XFERCOUNT); if (pxferCap) { pxferCap->SetCurrent((TW_UINT32)0); }
//
// return a cancel to abort the transfer.
// Applications will most commonly delete the current
// image, and keep the previous images.
//
twRc = TWRC_CANCEL; } else if (FAILED(hr)) { m_twStatus.ConditionCode = TWCC_FROM_HRESULT(hr); twRc = TWRC_FAILURE; }
return twRc; }
TW_UINT16 CWiaDataSrc::TransferToMemory(GUID guidFormatID) { DBG_FN_DS(CWiaDataSrc::TransferToMemory());
//
// set WIA format in Transfer Information structure
//
m_MemoryTransferInfo.mtiguidFormat = guidFormatID;
TW_UINT16 twRc = TWRC_FAILURE; HRESULT hr = E_FAIL; CWiaDataCallback DataCallback; CCap *pCap = NULL; pCap = FindCap(CAP_INDICATORS); if(pCap){ DataCallback.Initialize(NULL,pCap->GetCurrent()); } else { DataCallback.Initialize(NULL,TRUE); }
IWiaDataCallback *pIDataCB = NULL; hr = DataCallback.QueryInterface(IID_IWiaDataCallback,(void **)&pIDataCB); if (SUCCEEDED(hr)) { hr = m_pDevice->LoadImage(m_pCurrentIWiaItem, guidFormatID, pIDataCB); if (SUCCEEDED(hr)) { if(SUCCEEDED(DataCallback.GetImage(&m_hMemXferBits, NULL))){
//
// check for DIB data (special case)
// If we are acquiring DIB data, then we have to apply the
// height rules:
// positive = image is right side up
// negative = image is up side down
// zero = image has an unknown length (and assumed to be upside down)
if(WiaImgFmt_MEMORYBMP == guidFormatID){
//
// for memory transfers we need to make sure that the image
// is upside down in memory, so the application can assemble
// the bands correctly.
//
FlipDIB(m_hMemXferBits, TRUE); }
m_ImageHeight = (TW_UINT32)DataCallback.GetImageHeight(); m_ImageWidth = (TW_UINT32)DataCallback.GetImageWidth(); m_hCachedImageData = m_hMemXferBits; twRc = TWRC_SUCCESS; } } pIDataCB->Release(); pIDataCB = NULL; }
//
// check for a cancel, or out-of-paper error (scanners could return this)
//
if ((S_FALSE == hr) || (WIA_ERROR_PAPER_EMPTY == hr)) { m_twStatus.ConditionCode = TWCC_SUCCESS;
if(WIA_ERROR_PAPER_EMPTY == hr) { DBG_TRC(("CWiaDataSrc::TransferToMemory(), WIA_ERROR_PAPER_EMPTY returned from source.")); }
//
// set XFERCOUNT
//
CCap *pxferCap = FindCap(CAP_XFERCOUNT); if (pxferCap) { pxferCap->SetCurrent((TW_UINT32)0); }
//
// return a cancel to abort the transfer.
// Applications will most commonly delete the current
// image, and keep the previous images.
//
twRc = TWRC_CANCEL; } else if (FAILED(hr)) { m_twStatus.ConditionCode = TWCC_FROM_HRESULT(hr); twRc = TWRC_FAILURE; }
return twRc; }
TW_UINT16 CWiaDataSrc::GetCachedImage(HGLOBAL *phImage) { DBG_FN_DS(CWiaDataSrc::GetCachedImage()); TW_UINT16 twRc = TWRC_FAILURE; if(phImage){ if (m_hCachedImageData) { *phImage = m_hCachedImageData;
//
// since we are giving out the cached data
// reset the cache handle to NULL;
//
m_hCachedImageData = NULL; m_hMemXferBits = NULL; twRc = TWRC_SUCCESS; } } return twRc; }
TW_UINT16 CWiaDataSrc::TransferToThumbnail(HGLOBAL *phThumbnail) { DBG_FN_DS(CWiaDataSrc::TransferToThumbnail()); TW_UINT16 twRc = TWRC_FAILURE; HRESULT hr = E_FAIL; hr = m_pDevice->LoadThumbnail(m_pCurrentIWiaItem,phThumbnail,NULL); if (SUCCEEDED(hr)) { twRc = TWRC_XFERDONE; } return twRc; }
TW_UINT16 CWiaDataSrc::GetCommonSettings() { DBG_FN_DS(CWiaDataSrc::GetCommonSettings()); TW_UINT16 twRc = TWRC_FAILURE;
//
// Some TWAIN applications make the assumption that the TWAIN data source
// defaults to BMP/DIB data formats. This is on the basis that TWAIN
// spec minimal requirements are BMP/DIB. WIA minimal requirements are
// BMP/DIB. Set the current Format GUID to MEMORYBMP, and TYMED to
// TYMED_CALLBACK. This will set the WIA driver to transfer bitmap data
// by default. This does not limit the data types in any way. A high
// end application will properly read the valid TWAIN values and configure
// the device to do the correct thing.
//
//
// before configuring TWAIN valid values, set the WIA device to TYMED_CALLBACK, MEMORYBMP.
//
HRESULT hr = S_OK; CWiahelper WIA; hr = WIA.SetIWiaItem(m_pCurrentIWiaItem); if (FAILED(hr)) { DBG_ERR(("CWiaDataSrc::GetCommonSettings(), failed to set IWiaItem for property writing")); return twRc; }
hr = WIA.WritePropertyLong(WIA_IPA_TYMED,TYMED_CALLBACK); if(FAILED(hr)){ DBG_ERR(("CWiaDataSrc::GetCommonSettings(), failed to set TYMED_CALLBACK as a default setting")); return twRc; }
hr = WIA.WritePropertyGUID(WIA_IPA_FORMAT,WiaImgFmt_MEMORYBMP); if(FAILED(hr)){ DBG_ERR(("CWiaDataSrc::GetCommonSettings(), failed to set WiaImgFmt_MEMORYBMP as a default setting")); return twRc; }
if (TWRC_SUCCESS == GetPixelTypes()) { if (TWRC_SUCCESS == GetCompressionTypes()) { if (TWRC_SUCCESS == GetBitDepths()) { if (TWRC_SUCCESS == GetImageFileFormats()) { twRc = TWRC_SUCCESS; } else { DBG_ERR(("CWiaDataSrc::GetCommonSettings(), GetImageFileFormats()")); } } else { DBG_ERR(("CWiaDataSrc::GetCommonSettings(), GetBitDepths() failed")); } } else { DBG_ERR(("CWiaDataSrc::GetCommonSettings(), GetCompressionTypes() failed")); } } else { DBG_ERR(("CWiaDataSrc::GetCommonSettings(), GetPixelTypes() failed")); }
return twRc; }
TW_UINT16 CWiaDataSrc::GetCommonDefaultSettings() { DBG_FN_DS(CWiaDataSrc::GetCommonDefaultSettings()); TW_UINT16 twRc = TWRC_FAILURE; CCap *pCap = NULL; TW_UINT16 CapDataArray[1];
pCap = FindCap(ICAP_PIXELTYPE); if (pCap) { CapDataArray[0] = TWPT_RGB; twRc = pCap->Set(0,0,1,(BYTE*)CapDataArray); if (TWRC_SUCCESS == twRc) {
pCap = FindCap(ICAP_COMPRESSION); if (pCap) { CapDataArray[0] = TWCP_NONE; twRc = pCap->Set(0,0,1,(BYTE*)CapDataArray);
pCap = FindCap(ICAP_BITDEPTH); if (pCap) { CapDataArray[0] = 24; twRc = pCap->Set(0,0,1,(BYTE*)CapDataArray); if (TWRC_SUCCESS == twRc) {
pCap = FindCap(ICAP_IMAGEFILEFORMAT); if (pCap) { CapDataArray[0] = TWFF_BMP; twRc = pCap->Set(0,0,1,(BYTE*)CapDataArray); if (TWRC_SUCCESS == twRc) {
} } } } } } } return twRc; }
TW_UINT16 CWiaDataSrc::GetPixelTypes() { DBG_FN_DS(CWiaScannerDS::GetPixelTypes()); TW_UINT16 twRc = TWRC_FAILURE;
CCap *pCap = FindCap(ICAP_PIXELTYPE); if (pCap) {
HRESULT hr = S_OK; CWiahelper WIA; hr = WIA.SetIWiaItem(m_pCurrentIWiaItem); if (FAILED(hr)) { DBG_ERR(("CWiaDataSrc::GetPixelTypes(), failed to set IWiaItem for property reading")); return twRc; }
TW_UINT32 ActualCount = 0; TW_UINT32 CurrentIndex = 0; TW_UINT32 DefaultIndex = 0; TW_UINT16 *pPixelTypeArray = NULL;
//
// read current value, for default and current index settings
//
LONG lCurrentDataTypeValue = WIA_DATA_COLOR;
//
// read current WIA_IPA_DATATYPE setting
//
hr = WIA.ReadPropertyLong(WIA_IPA_DATATYPE,&lCurrentDataTypeValue); if (SUCCEEDED(hr)) {
//
// read valid values for WIA_IPA_DATATYPE
//
PROPVARIANT pv; memset(&pv,0,sizeof(pv)); LONG lAccessFlags = 0; hr = WIA.ReadPropertyAttributes(WIA_IPA_DATATYPE,&lAccessFlags,&pv); if (SUCCEEDED(hr)) { if (lAccessFlags & WIA_PROP_LIST) {
//
// for each valid WIA value in the LIST, set a corresponding
// TWAIN value
//
pPixelTypeArray = new TW_UINT16[WIA_PROP_LIST_COUNT(&pv)]; if (pPixelTypeArray) { memset(pPixelTypeArray,0,(sizeof(TW_UINT16)*WIA_PROP_LIST_COUNT(&pv))); for (ULONG i = 0; i < WIA_PROP_LIST_COUNT(&pv);i++) {
switch (pv.caul.pElems[i+2]) { case WIA_DATA_THRESHOLD: pPixelTypeArray[ActualCount] = (TW_UINT16)TWPT_BW; if (lCurrentDataTypeValue == WIA_DATA_THRESHOLD) { CurrentIndex = ActualCount; } ActualCount++; DBG_TRC(("WIA driver supports WIA_DATA_THERSHOLD -> TWPT_BW")); break; case WIA_DATA_GRAYSCALE: pPixelTypeArray[ActualCount] = (TW_UINT16)TWPT_GRAY; if (lCurrentDataTypeValue == WIA_DATA_GRAYSCALE) { CurrentIndex = ActualCount; } ActualCount++; DBG_TRC(("WIA driver supports WIA_DATA_GRAYSCALE -> TWPT_GRAY")); break; case WIA_DATA_COLOR: pPixelTypeArray[ActualCount] = (TW_UINT16)TWPT_RGB; if (lCurrentDataTypeValue == WIA_DATA_COLOR) { CurrentIndex = ActualCount; } ActualCount++; DBG_TRC(("WIA driver supports WIA_DATA_COLOR -> TWPT_RGB")); break; case WIA_DATA_DITHER: case WIA_DATA_COLOR_THRESHOLD: case WIA_DATA_COLOR_DITHER: ////////////////////////////////
// NO TWAIN -> WIA CONVERSION //
////////////////////////////////
//
// TWPT_PALETTE
// TWPT_CMY
// TWPT_CMYK
// TWPT_YUV
// TWPT_YUVK
// TWPT_CIEXYZ
default: DBG_TRC(("WIA Data Type (%d) does not MAP to TWAIN a pixel type",pv.caul.pElems[i+2])); break; } } } else { DBG_ERR(("CWiaDataSrc::GetPixelTypes(), failed to allocate Pixel Type Array Memory")); } } else {
//
// we only have 1 value, so make it the current, default and valid value.
//
pPixelTypeArray = new TW_UINT16[1]; if (pPixelTypeArray) { memset(pPixelTypeArray,0,(sizeof(TW_UINT16)));
switch (lCurrentDataTypeValue) { case WIA_DATA_THRESHOLD: pPixelTypeArray[ActualCount] = (TW_UINT16)TWPT_BW; if (lCurrentDataTypeValue == WIA_DATA_THRESHOLD) { CurrentIndex = ActualCount; } ActualCount++; DBG_TRC(("WIA driver supports WIA_DATA_THERSHOLD -> TWPT_BW")); break; case WIA_DATA_GRAYSCALE: pPixelTypeArray[ActualCount] = (TW_UINT16)TWPT_GRAY; if (lCurrentDataTypeValue == WIA_DATA_GRAYSCALE) { CurrentIndex = ActualCount; } ActualCount++; DBG_TRC(("WIA driver supports WIA_DATA_GRAYSCALE -> TWPT_GRAY")); break; case WIA_DATA_COLOR: pPixelTypeArray[ActualCount] = (TW_UINT16)TWPT_RGB; if (lCurrentDataTypeValue == WIA_DATA_COLOR) { CurrentIndex = ActualCount; } ActualCount++; DBG_TRC(("WIA driver supports WIA_DATA_COLOR -> TWPT_RGB")); break; case WIA_DATA_DITHER: case WIA_DATA_COLOR_THRESHOLD: case WIA_DATA_COLOR_DITHER: ////////////////////////////////
// NO TWAIN -> WIA CONVERSION //
////////////////////////////////
//
// TWPT_PALETTE
// TWPT_CMY
// TWPT_CMYK
// TWPT_YUV
// TWPT_YUVK
// TWPT_CIEXYZ
default: DBG_TRC(("WIA Data Type (%d) does not MAP to TWAIN a pixel type",lCurrentDataTypeValue)); break; } } else { DBG_ERR(("CWiaDataSrc::GetPixelTypes(), failed to allocate Pixel Type Array Memory")); } }
if (pPixelTypeArray) {
//
// default index is equal to current index, because we are stating that the WIA driver
// is a fresh start-up state.
//
DefaultIndex = CurrentIndex;
twRc = pCap->Set(DefaultIndex,CurrentIndex,ActualCount,(BYTE*)pPixelTypeArray,TRUE); // list
delete [] pPixelTypeArray; pPixelTypeArray = NULL;
//twRc = TWRC_SUCCESS;
}
PropVariantClear(&pv); } else { DBG_ERR(("CWiaDataSrc::GetPixelTypes(), failed to read WIA_IPS_DATATYPE attributes")); } } else { DBG_ERR(("CWiaDataSrc::GetPixelTypes(), failed to read WIA_IPS_DATATYPE current value")); } } return twRc; }
TW_UINT16 CWiaDataSrc::GetBitDepths() { DBG_FN_DS(CWiaScannerDS::GetBitDepths()); TW_UINT16 twRc = TWRC_FAILURE;
CCap *pCap = FindCap(ICAP_BITDEPTH); if (pCap) {
HRESULT hr = S_OK; CWiahelper WIA; hr = WIA.SetIWiaItem(m_pCurrentIWiaItem); if (FAILED(hr)) { DBG_ERR(("CWiaDataSrc::GetBitDepths(), failed to set IWiaItem for property reading")); return twRc; }
TW_UINT32 ActualCount = 0; TW_UINT32 CurrentIndex = 0; TW_UINT32 DefaultIndex = 0; TW_UINT16 BitDepthArray[MAX_BITDEPTHS]; memset(BitDepthArray,0,sizeof(BitDepthArray));
//
// read current value, for default and current index settings
//
LONG lCurrentDataTypeValue = WIA_DATA_COLOR; LONG lCurrentBitDepthValue = 24;
//
// read current WIA_IPA_DATATYPE setting
//
hr = WIA.ReadPropertyLong(WIA_IPA_DATATYPE,&lCurrentDataTypeValue); if (SUCCEEDED(hr)) {
//
// read current WIA_IPA_DEPTH setting
//
hr = WIA.ReadPropertyLong(WIA_IPA_DEPTH,&lCurrentBitDepthValue); if (SUCCEEDED(hr)) {
PROPVARIANT pv; memset(&pv,0,sizeof(pv)); LONG lAccessFlags = 0;
//
// read valid values for WIA_IPA_DATATYPE
//
hr = WIA.ReadPropertyAttributes(WIA_IPA_DATATYPE,&lAccessFlags,&pv); if (SUCCEEDED(hr)) {
//
// for each valid value, set it to the current setting, and read
// the valid values for WIA_IPA_DEPTH.
//
if (lAccessFlags & WIA_PROP_LIST) {
//
// set the WIA_IPA_DATATYPE to each valid value in the LIST
//
for (ULONG i = 0; i < WIA_PROP_LIST_COUNT(&pv);i++) {
hr = WIA.WritePropertyLong(WIA_IPA_DATATYPE,(LONG)pv.caul.pElems[i+2]); if (SUCCEEDED(hr)) {
//
// read valid values for WIA_IPA_DEPTH
//
lAccessFlags = 0; PROPVARIANT pvDepth; memset(&pvDepth,0,sizeof(pvDepth)); hr = WIA.ReadPropertyAttributes(WIA_IPA_DEPTH,&lAccessFlags,&pvDepth); if (SUCCEEDED(hr)) { LONG lBitDepth = 0; if (lAccessFlags & WIA_PROP_LIST) {
//
// copy each valid value in the LIST to the array
//
for (ULONG ulIndex = 0; ulIndex < WIA_PROP_LIST_COUNT(&pvDepth);ulIndex++) { lBitDepth = pvDepth.caul.pElems[ulIndex+2]; for (ULONG BitDepthArrayIndex = 0; BitDepthArrayIndex < MAX_BITDEPTHS; BitDepthArrayIndex++) {
if (BitDepthArray[BitDepthArrayIndex] == 0) {
//
// the current slot is (0) zero, so add the new bit depth value
//
BitDepthArray[BitDepthArrayIndex] = (TW_UINT16)lBitDepth; DBG_TRC(("WIA driver supports %d bit depth",lBitDepth)); ActualCount++;
//
// exit the loop
//
BitDepthArrayIndex = MAX_BITDEPTHS; } else if (BitDepthArray[BitDepthArrayIndex] == (TW_UINT16)lBitDepth) {
//
// bit depth is already in the list, so exit the loop
//
BitDepthArrayIndex = MAX_BITDEPTHS; } } } } else if (lAccessFlags & WIA_PROP_NONE) {
//
// read the current value for WIA_IPA_DEPTH
// and copy it to the array
//
hr = WIA.ReadPropertyLong(WIA_IPA_DEPTH,&lBitDepth); if (SUCCEEDED(hr)) { for (ULONG BitDepthArrayIndex = 0; BitDepthArrayIndex < MAX_BITDEPTHS; BitDepthArrayIndex++) {
if (BitDepthArray[BitDepthArrayIndex] == 0) {
//
// the current slot is (0) zero, so add the new bit depth value
//
BitDepthArray[BitDepthArrayIndex] = (TW_UINT16)lBitDepth; DBG_TRC(("WIA driver supports %d bit depth",lBitDepth)); ActualCount++;
//
// exit the loop
//
BitDepthArrayIndex = MAX_BITDEPTHS; } else if (BitDepthArray[BitDepthArrayIndex] == (TW_UINT16)lBitDepth) {
//
// bit depth is already in the list, so exit the loop
//
BitDepthArrayIndex = MAX_BITDEPTHS; } } } else { DBG_ERR(("CWiaDataSrc::GetBitDepths(), ReadPropertyLong(WIA_IPA_DEPTH) failed")); } }
//
// clean up the PROPVARIANT structure
//
PropVariantClear(&pvDepth); } } else { DBG_ERR(("CWiaDataSrc::GetBitDepths(), WritePropertyLong(WIA_IPA_DATATYPE) failed")); } } } else {
//
// we only have 1 value, so make it the current, default and valid value.
//
BitDepthArray[0] = (TW_UINT16)lCurrentBitDepthValue; ActualCount = 1; DBG_TRC(("WIA driver supports %d bit depth",lCurrentBitDepthValue)); }
//
// set the current values back
//
hr = WIA.WritePropertyLong(WIA_IPA_DATATYPE,lCurrentDataTypeValue); if (SUCCEEDED(hr)) { hr = WIA.WritePropertyLong(WIA_IPA_DEPTH,lCurrentBitDepthValue); }
for (ULONG BitDepthArrayIndex = 0; BitDepthArrayIndex < MAX_BITDEPTHS; BitDepthArrayIndex++) { if (BitDepthArray[BitDepthArrayIndex] == (TW_UINT16)lCurrentBitDepthValue) { CurrentIndex = BitDepthArrayIndex; BitDepthArrayIndex = MAX_BITDEPTHS; } }
//
// default index is equal to current index, because we are stating that the WIA driver
// is a fresh start-up state.
//
DefaultIndex = CurrentIndex;
twRc = pCap->Set(DefaultIndex,CurrentIndex,ActualCount,(BYTE*)BitDepthArray,TRUE); // list
//twRc = TWRC_SUCCESS;
PropVariantClear(&pv); } else { DBG_ERR(("CWiaDataSrc::GetBitDepths(), failed to read WIA_IPS_DATATYPE attributes")); } } else { DBG_ERR(("CWiaDataSrc::GetBitDepths(), ReadPropertyLong(WIA_IPA_DEPTH) failed")); } } else { DBG_ERR(("CWiaDataSrc::GetBitDepths(), ReadPropertyLong(WIA_IPA_DATATYPE) failed")); } }
return twRc; }
TW_UINT16 CWiaDataSrc::GetImageFileFormats() { DBG_FN_DS(CWiaScannerDS::GetImageFileFormats()); TW_UINT16 twRc = TWRC_FAILURE;
CCap *pCap = FindCap(ICAP_IMAGEFILEFORMAT); if (pCap) {
HRESULT hr = S_OK; CWiahelper WIA; hr = WIA.SetIWiaItem(m_pCurrentIWiaItem); if (FAILED(hr)) { DBG_ERR(("CWiaDataSrc::GetImageFileFormats(), failed to set IWiaItem for property reading")); return twRc; }
TW_UINT32 ActualCount = 0; TW_UINT32 CurrentIndex = 0; TW_UINT32 DefaultIndex = 0; TW_UINT16 *pFileTypeArray = NULL;
IWiaDataTransfer *pIWiaDataTransfer = NULL; TW_UINT32 TotalFileFormats = 0; IEnumWIA_FORMAT_INFO *pIEnumWIA_FORMAT_INFO = NULL; WIA_FORMAT_INFO pfe;
//
// read current value, for default and current index settings
//
GUID guidCurrentFileFormat = GUID_NULL; hr = WIA.ReadPropertyGUID(WIA_IPA_FORMAT,&guidCurrentFileFormat); if (SUCCEEDED(hr)) {
//
// collect valid values for image file format
//
hr = m_pCurrentIWiaItem->QueryInterface(IID_IWiaDataTransfer, (void **)&pIWiaDataTransfer); if (S_OK == hr) { hr = pIWiaDataTransfer->idtEnumWIA_FORMAT_INFO(&pIEnumWIA_FORMAT_INFO); if (SUCCEEDED(hr)) {
//
// count supported FILE formats
//
do { memset(&pfe,0,sizeof(pfe)); hr = pIEnumWIA_FORMAT_INFO->Next(1, &pfe, NULL); if (hr == S_OK) { if ((pfe.lTymed == TYMED_FILE) || (pfe.lTymed == TYMED_MULTIPAGE_FILE)) { TotalFileFormats++; } } } while (hr == S_OK);
//
// allocate supported FILE format array
//
pFileTypeArray = new TW_UINT16[TotalFileFormats]; if (pFileTypeArray) { memset(pFileTypeArray,0,(sizeof(TW_UINT16) * TotalFileFormats));
//
// reset enuerator
//
hr = pIEnumWIA_FORMAT_INFO->Reset(); if (SUCCEEDED(hr)) { do { memset(&pfe,0,sizeof(pfe)); hr = pIEnumWIA_FORMAT_INFO->Next(1, &pfe, NULL); if (hr == S_OK) {
if (pfe.lTymed == TYMED_MULTIPAGE_FILE) { if (pfe.guidFormatID == WiaImgFmt_TIFF) { pFileTypeArray[ActualCount] = (TW_UINT16)TWFF_TIFFMULTI; if (guidCurrentFileFormat == WiaImgFmt_TIFF) { CurrentIndex = ActualCount; } ActualCount++; DBG_TRC(("WIA driver supports WiaImgFmt_TIFF (Multipage) -> TWFF_TIFFMULTI")); } }
if (pfe.lTymed == TYMED_FILE) { if (pfe.guidFormatID == WiaImgFmt_BMP) { pFileTypeArray[ActualCount] = (TW_UINT16)TWFF_BMP; if (guidCurrentFileFormat == WiaImgFmt_BMP) { CurrentIndex = ActualCount; } ActualCount++; DBG_TRC(("WIA driver supports WiaImgFmt_BMP -> TWFF_BMP")); } else if (pfe.guidFormatID == WiaImgFmt_JPEG) { pFileTypeArray[ActualCount] = (TW_UINT16)TWFF_JFIF; if (guidCurrentFileFormat == WiaImgFmt_JPEG) { CurrentIndex = ActualCount; } ActualCount++; DBG_TRC(("WIA driver supports WiaImgFmt_JPEG -> TWFF_JFIF")); } else if (pfe.guidFormatID == WiaImgFmt_TIFF) { pFileTypeArray[ActualCount] = (TW_UINT16)TWFF_TIFF; if (guidCurrentFileFormat == WiaImgFmt_TIFF) { CurrentIndex = ActualCount; } ActualCount++; DBG_TRC(("WIA driver supports WiaImgFmt_TIFF -> TWFF_TIFF")); } else if (pfe.guidFormatID == WiaImgFmt_PICT) { pFileTypeArray[ActualCount] = (TW_UINT16)TWFF_PICT; if (guidCurrentFileFormat == WiaImgFmt_PICT) { CurrentIndex = ActualCount; } ActualCount++; DBG_TRC(("WIA driver supports WiaImgFmt_PICT -> TWFF_PICT")); } else if (pfe.guidFormatID == WiaImgFmt_PNG) { pFileTypeArray[ActualCount] = (TW_UINT16)TWFF_PNG; if (guidCurrentFileFormat == WiaImgFmt_PNG) { CurrentIndex = ActualCount; } ActualCount++; DBG_TRC(("WIA driver supports WiaImgFmt_PNG -> WiaImgFmt_PNG")); } else if (pfe.guidFormatID == WiaImgFmt_EXIF) { pFileTypeArray[ActualCount] = (TW_UINT16)TWFF_EXIF; if (guidCurrentFileFormat == WiaImgFmt_EXIF) { CurrentIndex = ActualCount; } ActualCount++; DBG_TRC(("WIA driver supports WiaImgFmt_EXIF -> TWFF_EXIF")); } else if (pfe.guidFormatID == WiaImgFmt_FLASHPIX) { pFileTypeArray[ActualCount] = (TW_UINT16)TWFF_FPX; if (guidCurrentFileFormat == WiaImgFmt_FLASHPIX) { CurrentIndex = ActualCount; } ActualCount++; DBG_TRC(("WIA driver supports WiaImgFmt_FLASHPIX -> TWFF_FPX")); } else if (pfe.guidFormatID == WiaImgFmt_UNDEFINED) { DBG_TRC(("WIA File Format WiaImgFmt_UNDEFINED does not MAP to TWAIN a file format")); } else if (pfe.guidFormatID == WiaImgFmt_EMF) { DBG_TRC(("WIA File Format WiaImgFmt_EMF does not MAP to TWAIN a file format")); } else if (pfe.guidFormatID == WiaImgFmt_WMF) { DBG_TRC(("WIA File Format WiaImgFmt_WMF does not MAP to TWAIN a file format")); } else if (pfe.guidFormatID == WiaImgFmt_GIF) { DBG_TRC(("WIA File Format WiaImgFmt_GIF does not MAP to TWAIN a file format")); } else if (pfe.guidFormatID == WiaImgFmt_PHOTOCD) { DBG_TRC(("WIA File Format WiaImgFmt_PHOTOCD does not MAP to TWAIN a file format")); } else if (pfe.guidFormatID == WiaImgFmt_ICO) { DBG_TRC(("WIA File Format WiaImgFmt_ICO does not MAP to TWAIN a file format")); } else if (pfe.guidFormatID == WiaImgFmt_CIFF) { DBG_TRC(("WIA File Format WiaImgFmt_CIFF does not MAP to TWAIN a file format")); } else if (pfe.guidFormatID == WiaImgFmt_JPEG2K) { DBG_TRC(("WIA File Format WiaImgFmt_JPEG2K does not MAP to TWAIN a file format")); } else if (pfe.guidFormatID == WiaImgFmt_JPEG2KX) { DBG_TRC(("WIA File Format WiaImgFmt_JPEG2KX does not MAP to TWAIN a file format")); } else {
}
////////////////////////////////
// NO TWAIN -> WIA CONVERSION //
////////////////////////////////
//
// TWFF_XBM
// TWFF_SPIFF
} } } while (hr == S_OK); }
if (pFileTypeArray) {
//
// default index is equal to current index, because we are stating that the WIA driver
// is a fresh start-up state.
//
DefaultIndex = CurrentIndex;
twRc = pCap->Set(DefaultIndex,CurrentIndex,ActualCount,(BYTE*)pFileTypeArray,TRUE); // list
delete [] pFileTypeArray; pFileTypeArray = NULL; //twRc = TWRC_SUCCESS;
} }
pIEnumWIA_FORMAT_INFO->Release(); pIEnumWIA_FORMAT_INFO = NULL; } else { DBG_ERR(("CWiaDataSrc::GetImageFileFormats(), pIWiaDataTransfer->idtEnumWIA_FORMAT_INFO() failed to enumerate supported file formats")); } pIWiaDataTransfer->Release(); pIWiaDataTransfer = NULL; } else { DBG_ERR(("CWiaDataSrc::GetImageFileFormats(), QueryInterface(IID_IWiaDataTransfer) failed")); } } } return twRc; }
TW_UINT16 CWiaDataSrc::GetCompressionTypes() { DBG_FN_DS(CWiaScannerDS::GetCompressionTypes()); TW_UINT16 twRc = TWRC_FAILURE;
CCap *pCap = FindCap(ICAP_COMPRESSION); if (pCap) {
#ifdef SUPPORT_COMPRESSION_TYPES
HRESULT hr = S_OK; CWiahelper WIA; hr = WIA.SetIWiaItem(m_pCurrentIWiaItem); if (FAILED(hr)) { DBG_ERR(("CWiaDataSrc::GetCompressionTypes(), failed to set IWiaItem for property reading")); return twRc; }
TW_UINT32 ActualCount = 0; TW_UINT32 CurrentIndex = 0; TW_UINT32 DefaultIndex = 0; TW_UINT16 *pCompressionTypeArray = NULL;
//
// read current value, for default and current index settings
//
LONG lCurrentCompressionTypeValue = WIA_COMPRESSION_NONE; hr = WIA.ReadPropertyLong(WIA_IPA_COMPRESSION,&lCurrentCompressionTypeValue); if (SUCCEEDED(hr)) {
PROPVARIANT pv; memset(&pv,0,sizeof(pv)); LONG lAccessFlags = 0; hr = WIA.ReadPropertyAttributes(WIA_IPA_COMPRESSION,&lAccessFlags,&pv); if (SUCCEEDED(hr)) {
//
// collect valid values for compression type
//
if (lAccessFlags & WIA_PROP_LIST) { pCompressionTypeArray = new TW_UINT16[WIA_PROP_LIST_COUNT(&pv)]; if (pCompressionTypeArray) { memset(pCompressionTypeArray,0,(sizeof(TW_UINT16)*WIA_PROP_LIST_COUNT(&pv))); for (ULONG i = 0; i < WIA_PROP_LIST_COUNT(&pv);i++) {
switch (pv.caul.pElems[i+2]) { case WIA_COMPRESSION_NONE: pCompressionTypeArray[ActualCount] = (TW_UINT16)TWCP_NONE; if (lCurrentCompressionTypeValue == WIA_COMPRESSION_NONE) { CurrentIndex = ActualCount; } ActualCount++; DBG_TRC(("WIA driver supports WIA_COMPRESSION_NONE -> TWCP_NONE")); break; case WIA_COMPRESSION_G3: pCompressionTypeArray[ActualCount] = (TW_UINT16)TWCP_GROUP31D; if (lCurrentCompressionTypeValue == WIA_COMPRESSION_G3) { CurrentIndex = ActualCount; } ActualCount++; DBG_TRC(("WIA driver supports WIA_COMPRESSION_G3 -> TWCP_GROUP31D")); break; case WIA_COMPRESSION_G4: pCompressionTypeArray[ActualCount] = (TW_UINT16)TWCP_GROUP4; if (lCurrentCompressionTypeValue == WIA_COMPRESSION_G4) { CurrentIndex = ActualCount; } ActualCount++; DBG_TRC(("WIA driver supports WIA_COMPRESSION_G4 -> TWCP_GROUP4")); break; case WIA_COMPRESSION_JPEG: pCompressionTypeArray[ActualCount] = (TW_UINT16)TWCP_JPEG; if (lCurrentCompressionTypeValue == WIA_COMPRESSION_JPEG) { CurrentIndex = ActualCount; } ActualCount++; DBG_TRC(("WIA driver supports WIA_COMPRESSION_JPEG -> TWCP_JPEG")); break; case WIA_COMPRESSION_BI_RLE4: pCompressionTypeArray[ActualCount] = (TW_UINT16)TWCP_RLE4; if (lCurrentCompressionTypeValue == WIA_COMPRESSION_BI_RLE4) { CurrentIndex = ActualCount; } ActualCount++; DBG_TRC(("WIA driver supports WIA_COMPRESSION_BI_RLE4 -> TWCP_RLE4")); break; case WIA_COMPRESSION_BI_RLE8: pCompressionTypeArray[ActualCount] = (TW_UINT16)TWCP_RLE8; if (lCurrentCompressionTypeValue == WIA_COMPRESSION_BI_RLE8) { CurrentIndex = ActualCount; } ActualCount++; DBG_TRC(("WIA driver supports WIA_COMPRESSION_BI_RLE8 -> TWCP_RLE8")); break; ////////////////////////////////
// NO TWAIN -> WIA CONVERSION //
////////////////////////////////
//
// TWCP_PACKBITS
// TWCP_GROUP31D
// TWCP_GROUP31DEOL
// TWCP_GROUP32D
//
//
// TWCP_LZW
// TWCP_JBIG
default: DBG_TRC(("WIA Compression Type (%d) does not MAP to TWAIN a compression type",pv.caul.pElems[i+2])); break; } } } else { DBG_ERR(("CWiaDataSrc::GetCompressionTypes(), failed to allocate Compression Type Array Memory")); } } else {
//
// current value becomes the only valid value
//
CurrentIndex = 0; ActualCount = 1;
pCompressionTypeArray = new TW_UINT16[1]; if (pCompressionTypeArray) { switch (lCurrentCompressionTypeValue) { case WIA_COMPRESSION_NONE: pCompressionTypeArray[0] = (TW_UINT16)TWCP_NONE; DBG_TRC(("WIA driver supports WIA_COMPRESSION_NONE -> TWCP_NONE")); break; case WIA_COMPRESSION_G3: pCompressionTypeArray[0] = (TW_UINT16)TWCP_GROUP31D; DBG_TRC(("WIA driver supports WIA_COMPRESSION_G3 -> TWCP_GROUP31D")); break; case WIA_COMPRESSION_G4: pCompressionTypeArray[0] = (TW_UINT16)TWCP_GROUP4; DBG_TRC(("WIA driver supports WIA_COMPRESSION_G4 -> TWCP_GROUP4")); break; case WIA_COMPRESSION_JPEG: pCompressionTypeArray[0] = (TW_UINT16)TWCP_JPEG; DBG_TRC(("WIA driver supports WIA_COMPRESSION_JPEG -> TWCP_JPEG")); break; case WIA_COMPRESSION_BI_RLE4: pCompressionTypeArray[0] = (TW_UINT16)TWCP_RLE4; DBG_TRC(("WIA driver supports WIA_COMPRESSION_BI_RLE4 -> TWCP_RLE4")); break; case WIA_COMPRESSION_BI_RLE8: pCompressionTypeArray[0] = (TW_UINT16)TWCP_RLE8; DBG_TRC(("WIA driver supports WIA_COMPRESSION_BI_RLE8 -> TWCP_RLE8")); break; ////////////////////////////////
// NO TWAIN -> WIA CONVERSION //
////////////////////////////////
//
// TWCP_PACKBITS
// TWCP_GROUP31D
// TWCP_GROUP31DEOL
// TWCP_GROUP32D
//
//
// TWCP_LZW
// TWCP_JBIG
default: DBG_TRC(("WIA Compression Type (%d) does not MAP to TWAIN a compression type",lCurrentCompressionTypeValue)); break; } } }
if (pCompressionTypeArray) {
//
// default index is equal to current index, because we are stating that the WIA driver
// is a fresh start-up state.
//
DefaultIndex = CurrentIndex;
twRc = pCap->Set(DefaultIndex,CurrentIndex,ActualCount,(BYTE*)pCompressionTypeArray,TRUE); // list
delete [] pCompressionTypeArray; pCompressionTypeArray = NULL;
//twRc = TWRC_SUCCESS;
}
PropVariantClear(&pv); } else { DBG_ERR(("CWiaDataSrc::GetCompressionTypes(), failed to read WIA_IPA_COMPRESSION attributes")); } } else { DBG_ERR(("CWiaDataSrc::GetCompressionTypes(), failed to read WIA_IPA_COMPRESSION current value")); } #else // SUPPORT_COMPRESSION_TYPES
//
// support only TWCP_NONE (no Compression)
//
TW_UINT16 CapDataArray[1]; CapDataArray[0] = TWCP_NONE; twRc = pCap->Set(0,0,1,(BYTE*)CapDataArray);
#endif // SUPPORT_COMPRESSION_TYPES
} return twRc; }
TW_UINT16 CWiaDataSrc::SetCommonSettings(CCap *pCap) { DBG_FN_DS(CWiaScannerDS::SetCommonSettings()); HRESULT hr = S_OK; LONG lValue = 0; CWiahelper WIA; IWiaItem *pIRootItem = NULL; hr = WIA.SetIWiaItem(m_pCurrentIWiaItem); if (FAILED(hr)) { DBG_ERR(("CWiaDataSrc::SetCommonSettings(), failed to set IWiaItem for property reading")); }
//
// determine if it is a Capability that the device really needs to know
// about.
//
switch (pCap->GetCapId()) { case ICAP_PIXELTYPE: DBG_TRC(("CWiaDataSrc::SetCommonSettings(ICAP_PIXELTYPE)")); switch (pCap->GetCurrent()) { case TWPT_BW: DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_DATATYPE to WIA_DATA_THRESHOLD")); hr = WIA.WritePropertyLong(WIA_IPA_DATATYPE,WIA_DATA_THRESHOLD); if(FAILED(hr)){ DBG_ERR(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_DATATYPE to WIA_DATA_THRESHOLD failed")); } break; case TWPT_GRAY: DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_DATATYPE to WIA_DATA_GRAYSCALE")); hr = WIA.WritePropertyLong(WIA_IPA_DATATYPE,WIA_DATA_GRAYSCALE); if(FAILED(hr)){ DBG_ERR(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_DATATYPE to WIA_DATA_GRAYSCALE failed")); } break; case TWPT_RGB: DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_DATATYPE to WIA_DATA_COLOR")); hr = WIA.WritePropertyLong(WIA_IPA_DATATYPE,WIA_DATA_COLOR); if(FAILED(hr)){ DBG_ERR(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_DATATYPE to WIA_DATA_COLOR failed")); } break; case TWPT_PALETTE: case TWPT_CMY: case TWPT_CMYK: case TWPT_YUV: case TWPT_YUVK: case TWPT_CIEXYZ: default: DBG_WRN(("CWiaDataSrc::SetCommonSettings(), An unsupported ICAP_PIXELTYPE (%d) was sent to this data source",(LONG)pCap->GetCurrent())); break; } break; case ICAP_BITDEPTH: DBG_TRC(("CWiaDataSrc::SetCommonSettings(ICAP_BITDEPTH)")); lValue = (LONG)pCap->GetCurrent(); DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_BITDEPTH to %d",lValue)); hr = WIA.WritePropertyLong(WIA_IPA_DEPTH,lValue); if(FAILED(hr)){ DBG_ERR(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_BITDEPTH to %d failed",lValue)); } break; case ICAP_IMAGEFILEFORMAT: { DBG_TRC(("CWiaDataSrc::SetCommonSettings(ICAP_IMAGEFILEFORMAT)")); lValue = (LONG)pCap->GetCurrent(); LONG lTymed = TYMED_FILE; if (lValue == TWFF_TIFFMULTI) { DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_TYMED to TYMED_MULTIPAGE_FILE")); lTymed = TYMED_MULTIPAGE_FILE; } else { DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_TYMED to TYMED_FILE")); }
hr = WIA.WritePropertyLong(WIA_IPA_TYMED,lTymed);
GUID guidFormat = GUID_NULL;
if (SUCCEEDED(hr)) { switch (lValue) { case TWFF_TIFFMULTI: case TWFF_TIFF: guidFormat = WiaImgFmt_TIFF; DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_FORMAT to WiaImgFmt_TIFF")); break; case TWFF_PICT: guidFormat = WiaImgFmt_PICT; DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_FORMAT to WiaImgFmt_PICT")); break; case TWFF_BMP: guidFormat = WiaImgFmt_BMP; DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_FORMAT to WiaImgFmt_BMP")); break; case TWFF_JFIF: guidFormat = WiaImgFmt_JPEG; DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_FORMAT to WiaImgFmt_JPEG")); break; case TWFF_FPX: guidFormat = WiaImgFmt_FLASHPIX; DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_FORMAT to WiaImgFmt_FLASHPIX")); break; case TWFF_PNG: guidFormat = WiaImgFmt_PNG; DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_FORMAT to WiaImgFmt_PNG")); break; case TWFF_EXIF: guidFormat = WiaImgFmt_EXIF; DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_FORMAT to WiaImgFmt_EXIF")); break; case TWFF_SPIFF: case TWFF_XBM: default: break; }
hr = WIA.WritePropertyGUID(WIA_IPA_FORMAT,guidFormat); if (FAILED(hr)) { DBG_ERR(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_FORMAT to %d failed",lValue)); } } else { DBG_ERR(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_TYMED to %d failed",lTymed)); } } break; case ICAP_COMPRESSION: { DBG_TRC(("CWiaDataSrc::SetCommonSettings(ICAP_COMPRESSION)")); lValue = (LONG)pCap->GetCurrent(); LONG lCompression = WIA_COMPRESSION_NONE; switch (lValue) { case TWCP_NONE: lCompression = WIA_COMPRESSION_NONE; DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_COMPRESSION to WIA_COMPRESSION_NONE")); break; case TWCP_GROUP4: lCompression = WIA_COMPRESSION_G4; DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_COMPRESSION to WIA_COMPRESSION_G4")); break; case TWCP_JPEG: lCompression = WIA_COMPRESSION_JPEG; DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_COMPRESSION to WIA_COMPRESSION_JPEG")); break; case TWCP_RLE4: lCompression = WIA_COMPRESSION_BI_RLE4; DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_COMPRESSION to WIA_COMPRESSION_BI_RLE4")); break; case TWCP_RLE8: lCompression = WIA_COMPRESSION_BI_RLE8; DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_COMPRESSION to WIA_COMPRESSION_BI_RLE8")); break; case TWCP_GROUP31D: case TWCP_GROUP31DEOL: case TWCP_GROUP32D: lCompression = WIA_COMPRESSION_G3; DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_COMPRESSION to WIA_COMPRESSION_G3")); break; case TWCP_LZW: case TWCP_JBIG: case TWCP_PACKBITS: default: break; }
hr = WIA.WritePropertyLong(WIA_IPA_COMPRESSION,lCompression); if(FAILED(hr)){ DBG_ERR(("CWiaDataSrc::SetCommonSettings(), Setting WIA_IPA_COMPRESSION to %d failed",lCompression)); } } break; default: DBG_TRC(("CWiaDataSrc::SetCommonSettings(), data source is not setting CAPID = %x to WIA device (it is not needed)",pCap->GetCapId())); break; }
if (SUCCEEDED(hr)) { DBG_TRC(("CWiaDataSrc::SetCommonSettings(), Settings were successfully sent to WIA device")); } else { DBG_ERR(("CWiaDataSrc::SetCommonSettings(), Settings were unsuccessfully sent to WIA device")); return TWRC_FAILURE; }
return TWRC_SUCCESS; }
TW_UINT16 CWiaDataSrc::GetMemoryTransferBits(BYTE* pImageData) { DBG_FN_DS(CWiaScannerDS::GetMemoryTransferBits()); if(!pImageData){ return TWRC_FAILURE; }
BYTE *pBits = pImageData;
if (m_MemoryTransferInfo.mtiguidFormat == WiaImgFmt_MEMORYBMP) { BITMAPINFOHEADER* pbmh = (BITMAPINFOHEADER*)pImageData; if (pbmh) { pBits += sizeof(BITMAPINFOHEADER) + (pbmh->biClrUsed * sizeof(RGBQUAD)); } }
m_MemoryTransferInfo.mtipBits = pBits;
return TWRC_SUCCESS; }
|