ICAP_ZOOMFACTOR

Featured Clients

Sectors: FinanceInformation TechnoloyGovernmentHealthcareIndustriesEducation(show all)

TWAIN Capability: ICAP_ZOOMFACTOR

ICAP_ZOOMFACTOR

Description

When used with MSG_GET, return all camera supported lens zooming range.

Application

Use this capability with MSG_SET to select one of the lens zooming value that the Source supports.

Values

Type: TW_INT

Value after MSG_OPENDS: (may be remembered from a previous session)

After MSG_RESET/MSG_RESETALL: 0

Allowed Values: Source dependent.

Containers

MSG_GET TW_ONEVALUE TW_RANGE TW_ENUMERATION

MSG_GETCURRENT TW_ONEVALUE

MSG_GETDEFAULT TW_ONEVALUE

MSG_SET TW_ONEVALUE

MSG_SETCONSTRAINT TW_ONEVALUE

TW_RANGE TW_ENUMERATION

MSG_RESET TW_ONEVALUE

MSG_QUERYSUPPORT TW_ONEVALUE

Required By

None. Highly recommended for digital cameras that are equipped with zoom lenses.

TWAIN Version Introduced

Version 1.8

Chapter Contents

An Overview of Return Codes and Condition Codes 11-1

Currently Defined Return Codes 11-2

Currently Defined Condition Codes 11-3

Custom Return and Condition Codes 11-4

An Overview of Return Codes and Condition Codes

The TWAIN protocol defines no dynamic messaging system through which the application might determine, in real-time, what is happening in either the Source Manager or a Source. Neither does the protocol implement the native messaging systems built into the operating environments that TWAIN is defined to operate under (Microsoft Windows and Macintosh). This decision was made due to issues regarding platform specificity and higher-than-desired implementation costs. Instead, for each call the application makes to DSM_Entry , whether aimed at the Source Manager or a Source, the Source Manager returns an appropriate Return Code (TWRC_xxxx). The Return Code may have originated from the Source if that is where the original operation was destined. To get more specific status information, the application can use the DG_CONTROL DAT_STATUS MSG_GET operation to inquire the complimentary Condition Code (TWCC_xxxx) from the Source Manager or Source (whichever one originated the Return Code). The application should always check the Return Code. If the Return Code is TWRC_FAILURE, it should also check the Condition Code. This is especially important during capability negotiation. There are very few, if any, catastrophic error conditions for the application to worry about. Usually, the application will only have to “recover” from low memory errors caused from allocations in the Source. Most error conditions are handled by the Source Manager or, most typically, by the Source (often involving interaction with the user). If the Source fails in a way that is unrecoverable, it will ask to have its user interface disabled by sending the MSG_CLOSEDSREQ to the application’s event loop. The following operations can only return TWRC_SUCCESS or TWRC_FAILURE / TWCC_SEQERROR, if called in the wrong state. This is to avoid a situation where an Application is unable to shutdown a Source because of an error state, like the device being offline. The Source must comply with the request to change states.

DG_CONTROL DAT_PENDINGXFERS MSG_ENDXFER DG_CONTROL DAT_PENDINGXFERS MSG_RESET DG_CONTROL DAT_USERINTERFACE MSG_DISABLEDS DG_CONTROL DAT_IDENTITY MSG_CLOSEDS DG_CONTROL DAT_IDENTITY MSG_CLOSEDSM

When an Application receives this condition code, it alerts the user (so they can exit, if they wish). While waiting for the user response the Application polls the value of CAP_DEVICEONLINE. The device continues to be offline as long as this call returns TWCC_SUCCESS, with a value of FALSE. The state 3 operation DG_CONTROL DAT_IDENTITY MSG_OPENDS is the only one capable of returning TWCC_CHECKDEVICEONLINE. The Application cannot check CAP_DEVICEONLINE (since that is a state 4 operation), however, it can retry the MSG_OPENDS call, if it chooses.

Currently Defined Return Codes Code Description TWRC_BUSY Scanner busy, please retry your command again later.

TWRC_CANCEL Abort transfer or the Cancel button was pressed. TWRC_CHECKSTATUS Partially successful operation; request further information. TWRC_DSEVENT Event (or Windows message) belongs to this Source. TWRC_ENDOFLIST No more Sources found after MSG_GETNEXT.

TWRC_FAILURE Operation failed - get the Condition Code for more information.

TWRC_NOTDSEVENT Event (or Windows message) does not belong to this Source.

TWRC_SCANNERLOCKED Scanner is in use by another application, please retry your command again later.

TWRC_SUCCESS Operation was successful.

TWRC_XFERDONE All data has been transferred.

Currently Defined Condition Codes

The following are the currently defined condition codes: Code Description TWCC_BADCAP* Capability not supported by Source or operation (get, set) is not supported on capability, or capability had dependencies on other capabilities and cannot be operated upon at this time (Obsolete, see TWCC_CAPUNSUPPORTED, TWCC_CAPBADOPERATION, and TWCC_CAPSEQERROR).

TWCC_BADDEST Unknown destination in DSM_Entry.

TWCC_BADPROTOCOL Unrecognized operation triplet.

TWCC_BADVALUE Data parameter out of supported range.

TWCC_BUMMER General failure. Unload Source immediately.

TWCC_CAPBADOPERATION* Operation (i.e., Get or Set) not supported on capability.

TWCC_CAPSEQERROR* Capability has dependencies on other capabilities and cannot be operated upon at this time.

TWCC_CAPUNSUPPORTED* Capability not supported by Source.

TWCC_CHECKDEVICEONLINE Check the device status using CAP_DEVICEONLINE, this condition code can be returned by any TWAIN operation in state 4 or higher, or from the state 3 DG_CONTROL DAT_IDENTITY MSG_OPENDS. The state remains unchanged. If in state 4 the Application can poll with CAP_DEVICELINE until the value returns TRUE.

TWCC_DAMAGEDCORNER Operation failed because the document has a damaged corner.

TWCC_DENIED File System operation is denied (file is protected). TWCC_DOCTOODARK Operation failed because the document is too dark. TWCC_DOCTOOLIGHT Operation failed because the document is too light. TWCC_FILEEXISTS Operation failed because file already exists. TWCC_FILENOTFOUND File not found.

TWCC_FOCUSERROR Operation failed because of a focusing error during document capture.

TWCC_INTERLOCK Operation failed because the cover or door is open.

TWCC_LOWMEMORY Not enough memory to complete operation.

TWCC_MAXCONNECTIONS Source is connected to maximum supported number of applications.

TWCC_NODS Source Manager unable to find the specified Source. Code Description TWCC_NOMEDIA Source has nothing to capture for a transfer. Can be returned by DG_CONTROL DAT_USERINTERFACE MSG_ENABLEDS, by any of the DAT_IMAGE XFER operations, by DAT_IMAGEINFO or DAT_EXTIMAGEINFO.

TWCC_NOTEMPTY Operation failed because directory is not empty.

TWCC_OPERATIONERROR Source or Source Manager reported an error to the user and handled the error; no application action required.

TWCC_PAPERDOUBLEFEED Transfer failed because of a feeder error, this can be returned by any of the DAT_IMAGE XFER operations. When received the current TWAIN state remains unchanged.

TWCC_PAPERJAM Transfer failed because of a feeder error, this can be returned by any of the DAT_IMAGE XFER operations. When received the current TWAIN state remains unchanged.

TWCC_SEQERROR Illegal operation for current Source Manager or Source state.

TWCC_SUCCESS Operation worked.

* TWCC_BADCAP has been replaced with three new condition codes that more clearly specify the reason for a capability operation failure. For backwards compatibility applications should also accept TWCC_BADCAP and treat it as a general capability operation failure. No 1.6 Image Data Sources should return this condition code, but use the new ones instead.

Custom Return and Condition Codes

Although probably not necessary or desirable, it is possible to create custom Return Codes and Condition Codes. Refer to the TWAIN H file for the value of TWRC_CUSTOMBASE for custom Return Codes and TWCC_CUSTOMBASE for custom Condition Codes. All custom values must be numerically greater than these base values. Remember that the consumer of these custom values will look in your TW_IDENTITY.ProductName field to clarify what the identifier’s value means. There is no other protection against overlapping custom definitions. 12 Operating System Dependencies

Chapter Contents

Developing for Windows 12-1

Developing for Mac 12-8

Developing for Linux 12-12

This section describes the differences and requirements of developing TWAIN Applications and Sources on various operating systems. This section covers 32-bit and 64-bit Windows, Apple OS X version 10.2 and later, and Linux. Older operating systems are not described in this version of the specification. For older operating systems (16-bit Windows and Apple OS before version 10.2) please refer to version 1.9 of the Specification.

Developing for Windows

Installation of the Data Source Manager

All TWAIN 2.x Applications must use TWAINDSM.DLL. All TWAIN 2.x Sources must be prepared to work with either TWAINDSM.DLL or TWAIN_32.DLL, which may still be used by older Applications. Applications that wish to use access the Data Source Manager, must install it themselves. Please refer to the TWAIN website http://www.twain.org to obtain this file and for installation instructions. This DSM is fully backwards compatible with all versions of TWAIN. The Application Installer may include a Data Source Manager merge module: http://sourceforge.net/projects/twain-dsm/files/ The TWAIN DSM is a shared library named TWAINDSM.DLL. There is a 32-bit and a 64-bit version of this file. TWAINDSM.DLL is installed in the Windows System directory (normally C:\Windows\System32). If installing the 32-bit file on a 64-bit system, it needs to end up in the WOW64 System directory (normally C:\Windows\SysWow64). By including the TWAIN DSM merge module in the application installer, the DSM is installed in the correct location.

Load the TWAIN Source Manager and get the DSM_Entry

This process takes a TWAIN application from State 1 to 2. Load TWAINDSM DLL using the LoadLibrary routine. Get the DSM_Entry by using the GetProcAddress call. Applications must perform a dynamic run-time link to DSM_Entry by calling LoadLibrary . If the Application has a dynamic link, however, it will be able to give users a meaningful error message, and perhaps continue with image acquisition facilities disabled. After loading the DSM, the application must check LoadLibrary return code. If it is NULL, it means that the Source Manager has not been installed on the user’s machine and the application cannot provide any TWAIN services to the user. If DSM_Entry returned by GetProcAddress is NULL, the application must not attempt to call pDSM_Entry as this would result in an Unrecoverable Application Error (UAE). On Windows the official TWAINDSM.dll is signed. This digital signature can be verified to check if an official version is being used. See http://twain-samples.svn.sourceforge.net.

OpenDSM

To Move from State 2 to State 3 The Application must provide a pointer to hWnd in pParent. It is strongly recommended that all TWAIN calls be made from a single thread.

OpenDS

To Move from State 3 to State 4 The Source Manager does a LoadLibrary of the Source and passes the OpenDS triplet to the Source. When the Source Manager receives a success from a Source, it increases its internal counter for this application having the specified Source open.

CloseDS

To Move from State 4 to State 3 The Source Manager forwards this triplet to the Source. The Source immediately prepares to terminate execution. When the Source Manager receives a success from a Source, it decrements its internal counter to see whether this application still has the specified Source open. If not, the Source Manager removes it from memory (It does a FreeLibrary of the Source).

Unload DSM

To Move from State 2 to State 1 Once the Source Manager has been closed, the application must unload the DLL from memory before continuing.

Use FreeLibrary hDSMLib where hDSMLib is the handle to the Source Manager DLL returned from the call to LoadLibrary seen earlier (in the State 1 to 2 section).

Function Declaration

The keyword FAR is included in the entry point syntax for legacy reasons. It has no value for any supported operating system, and is defined as an empty value. See Twain.h for details.

Memory Management in TWAIN

When TWAIN 2.x Applications and Sources connect to TWAINDSM.DLL, they must use the memory functions supplied by the DSM. When a TWAIN Source is connected to a legacy TWAIN 1.x DSM it must use these legacy WIN32 Global Memory functions:

GlobalAlloc GlobalFree GlobalLock GlobalUnlock

Using DAT_CALLBACK and DAT_NULL for Messages from the Source to the Application Sources

TWAIN sources use the DG_CONTROL DAT_NULL to return events like MSG_XFERREADY. If the callback pointer is supplied by the DSM, then the DS must use it. If not, it must use the Data Source Manager entry point DSM_ENTRY. MSG_INVOKECALLBACK was immediately deprecated for Windows and Linux Sources after implementing and should not be used.

Alter the Application’s Message Loop

Messages include activities such as key clicks, mouse events, periodic events, accelerators, etc. Every TWAIN-compliant application on Windows needs a message loop. These actions are called messages; however, this may be confusing as TWAIN uses the term “messages” to describe the third parameter of an operation triplet. Therefore, we will refer to these key clicks, etc. as events in this section generically. During a TWAIN session, the application opens one or more Sources. However, even if several Sources are open, the application should only have one Source enabled at any given time. That is the Source from which the user is attempting to acquire data. Altering the message loop is required so that the source can respond to Windows messages. Message Loop Modification - Passing messages

While a Source is enabled, all messages are sent to the application’s message loop. Some of the messages may belong to the application but others belong to the enabled Source. To ensure that the Source receives and processes its messages, the following changes are required: The application must send all Windows messages that it receives in its message loop to the Source, as long as the Source is enabled. The application uses:

DG_CONTROL DAT_EVENT MSG_PROCESSEVENT

The TW_EVENT data structure looks like this:

typedef struct {

TW_MEMREF pEvent Windows pMSG

TW_UINT TWMessage TW message from Source to

the application

} TW_EVENT FAR pTW_EVENT

The pEvent field points to the message structure. The Source receives the message from the Source Manager and determines if the message belongs to it. If it does, the Source processes the message. It then sets the Return Code to TWRC_DSEVENT to indicate it was a Source message. In addition, it should set the TWMessage field of the TW_EVENT structure to MSG_NULL.

If it does not, the Source sets the Return Code to TWRC_NOTDSEVENT, meaning it is not a Source message. In addition, it should set the TWMessage field of the TW_EVENT structure to MSG_NULL. The application receives this information from DSM_Entry and should process the message in its message loop as normal.

DAT_EVENT Handling Errors

One of the most common problems between a data source and application is the management of DG_CONTROL DAT_EVENT MSG_PROCESSEVENT. The symptoms are not immediately obvious, so it is worth mentioning them to assist new developers in quickly identifying and solving the problem. Cannot use TAB or Keyboard Shortcuts to Navigate TWAIN Dialog

The cause of this can be one of two things. Either the application is not forwarding all messages to TWAIN through the DAT_EVENT mechanism, or the data source is not properly processing the DAT_EVENT messages. (Windows: calling IsDialogMessage for each forwarded message with TWAIN Dialog handle.) TWAIN Dialog Box Combo Boxes cannot be opened / Edit boxes produce multiple chars per keystroke

This case is caused by processing TWAIN Dialog Messages twice. Either the data source has not returned the proper return code in response to DAT_EVENT calls (Windows: TWRC_DSEVENT when IsDialogMessage returns TRUE), or the application is ignoring the return code. Problem seems erratic, keyboard shortcuts and Tab key work for Message Boxes, but not TWAIN Dialog

This observation often further confuses the issue. In Windows, a standard Message box is Modal, and operates from a local message pump until the user closes it. All messages are properly dispatched to the message box since it does not rely on the application message pump. The TWAIN Dialog is slightly different since it is implemented Modeless. There is no easy way to duplicate Modal behavior for the TWAIN Dialog. Refer to the function EnableDS , in the TWAIN application sample file main.cpp at http://twain-samples.svn.sourceforge.net, to see an example of how to modify the message loop for Windows.

The Structure of a Source

The following sections describe the structure of a source Implementation

The Source is implemented as a Dynamic Link Library (DLL). The DLL runs within the calling application’s heap, although DLLs may be able to allocate their own heap and stack space. There is only one copy of the DLL’s code and data loaded at run-time per application. For more information regarding DLLs please refer to Microsoft documents. Naming and Location

The DLL’s file name must end with a .DS extension. The Source Manager recursively searches for your Source in the TWAIN sub-directory of the Windows directory. The name of the TWAIN directory is "twain_32" for 32-bit Sources and "twain_64" for 64-bit Sources (on 64-bit systems only). To reduce the chance for naming collisions, each Source should create a sub-directory beneath TWAIN giving it a name relevant to their product. The Source DLLs are placed there. Supporting files may be placed there as well, but since this is a system directory that may only be modifiable by a System Administrator, Sources must not write any information into this directory after installation. Entry Points and Segment Attributes

Every Source is required to have an entry point called DS_Entry (see Chapter 6, "Entry Points and Triplet Components") which must have the stdcall calling style. General Notes

DllMain entry point - This function is called by the loader when it loads or unloads a DLL. See http://www.microsoft.com for more details.

Sources UI and Handling Windows Messages

When a Source is enabled (i.e. States 5, 6, and 7), the application must pass all messages to the Source. Since the Source runs subservient to the application, this ensures that the Source will receive all messages for its window. The message will be passed in the TW_EVENT data structure that is referenced by a DG_CONTROL DAT_EVENT MSG_PROCESSEVENT command. Routing all messages, to all connected Sources while they are enabled, places a burden on the application and creates a potential performance bottleneck. Therefore, the Source must process the incoming messages as quickly as possible. The Source should examine each incoming operation before doing anything else. Only one operation’s message field says MSG_PROCESSEVENT so always look at the message field first. If it indicates MSG_PROCESSEVENT then immediately determine if the message belongs to the Source: If it does

Set the Return Code for the operation to TWRC_DSEVENT

Set the TWMessage field to MSG_NULL

Process the message Return to the application

Else

Set the Return Code to TWRC_NOTDSEVENT Set the TWMessage field to MSG_NULL Return to the application immediately

If the Source developer fails to process messages with this high priority, the user may see degraded performance whenever the Source is frontmost, which reflects poorly on the Source. On Windows, the code fragment looks like the following:

TW_UINT FAR PASCAL DS_Entry pTW_IDENTITY pSrc TW_UINT DG

TW_UINT DAT

TW_UINT MSG

TW_MEMREF pData

{

TWMSG twMsg TW_UINT twRc

Valid states – or – if CAP_DEVICEEVENTS has been negotiated to anything other than its default value of an empty TW_ARRAY As soon as the application has enabled the Source it must being sending the Source events This allows the Source to receive events to update its user interface and to return messages to the application The app sends down ALL message the Source decides which ones apply to it

if MSG MSG_PROCESSEVENT

{

if hImageDlg IsDialogMessage hImageDlg LPMSG pTW_EVENT pData >pEvent

{

twRc TWRC_DSEVENT

The source should for proper form return a MSG_NULL for all Windows messages processed by the Data Source

pTW_EVENT pData >TWMessage MSG_NULL

}

else

{

notify the application that the source did not consume this message

twRc TWRC_NOTDSEVENT

pTW_EVENT pData >TWMessage MSG_NULL

}

}

else

{

This is a Twain message process accordingly The remainder of the Source’s code follows

}

return twRc

}

The Windows IsDialogMessage call is used in this example. Sources can also use other Windows calls such as TranslateAccelerator and TranslateMDISYSAccel . If the Source has more than one window it has to check all of them and process the target one.

Native Transfer Mode

Every Source must support Native transfer mode. It is the default mode and is the easiest for an application to implement, however it is restrictive and the format is limited to the Device Independent Bitmap (DIB) when implementing on Windows. Set pHandle pointing to a handle to a DIB in memory. The Source will allocate the image buffer and return the handle to the address specified. Format the data block as a DIB. Use l DSM_MemAllocate (or GlobalAlloc for 1.x or less DSM) The following assignment will work in Windows:

TW_HANDLE pHandle hDIB

See the Windows SDK documentation under Structures: BIMAPINFO BITMAPINFOHEADER RGBQUAD. See also “DIBs and their use” by Ron Gery, in the Microsoft Development Library (MSDN CD). Note:

Follow the BITMAPINFOHEADER with the color table if required

Color table entries are RGBQUADs, which are stored in memory as BGR not RGB.

For 24-bit color DIBs, the “pixels” are also stored in BGR order, not RGB.

DIBs are stored ‘upside-down’ - the first pixel in the DIB is the lower-left corner of the image, and the last pixel is the upper-right corner.

Pixels in 1, 4, and 8 bit DIBs are “always” color table indices, you must index through the color table to determine the color value of a pixel. Every scanline is DWORD-aligned. The scanline is buffered to alignment; the buffering is not necessarily 0.

Native Audio format is WAV handle

File Transfer

The TW_SETUPFILEXFER pSetupFile >FileName = name of file must include the complete path and name

pSetupFile >VRefNum = is not used

Developing for Mac

Mac OS X includes high-level native development environment that you can use for your application’s graphical user interface: Cocoa. This is full-featured development environment in its own right. Note that Cocoa libraries are 32 and 64-bit. (See http://developer.apple.com). Only the Intel platform is supported, starting from OS X 10.6. Since Mac OS X 10.7 Apple supports 64-bit Intel Macs only. To allow native, 64-bit TWAIN Applications to access TWAIN Data Sources without any legacy compatibility mode, Data Sources must include 64-bit support. A 32-bit version can and should still be installed to support older Applications and older Mac OS X versions Because Cocoa changes the event handling mechanism (no WaitNextEvent loops), these paragraphs update and extend the section of the previous specification that describes how to modify the application event loop to support TWAIN. Cocoa-based Mac OS X TWAIN applications are required to supply an event handler callback function that the TWAIN DSM will call.

Installation of the Data Source Manager

Apple provides /System/Library/Frameworks/TWAIN.framework for access to the 1.x Data Source Manager. For Mac OS X version 10.2 and later, the Source Manager is installed automatically with the OS and developers should not install or modify TWAIN.framework. For TWAIN 2.x compatibility vendor's may choose to install the TWAIN Working Group's TWAINDSM.framework into /Library/Frameworks/. The directory “TWAIN Data Sources” should be created in "/Library/Image Capture" if it does not exist. If you are a scanner vendor, install your scanner data sources into a subdirectory of "/ Library/Image Capture/TWAIN Data Sources" directory.

Load the TWAIN Source Manager and get the DSM_Entry

This process takes a TWAIN application from State 1 to 2.

Link against TWAIN.framework. The Source Manager is a mach-o framework (TWAIN.framework). When building your application, you should link against TWAIN.framework. There should be no need to check for an existing Source Manager - beginning with Mac OS X 10.2, the TWAIN.framework is part of Mac OS X. For TWAIN 2.x compatibility dynamically load the /Library/Frameworks/ TWAINDSM.framework instead of static linking against the legacy TWAIN.framework. In case of failure fall back to loading the system's default TWAIN 1.x DSM from /System/Library/ Frameworks/TWAINDSM.framework.

OpenDSM

To Move from State 2 to State 3 Application must set pParent to NULL

OpenDS

The Source Manager does a dsOpen of the Source and sends an OpenDS triplet to the Source.

CloseDS

Closes the Source and removes it from memory by calling dsClose, following receipt of TWRC_SUCCESS from the Source.

Unload DSM

To Move from State 2 to State 1 No action is necessary.

Function Declaration

The keyword FAR is included in the entry point syntax for legacy reasons. It has no value for any supported operating system, and is defined as an empty value. See Twain.h for details.

Using DAT_CALLBACK and DAT_NULL for Messages from the Source to the Application Sources

TWAIN sources that do not detect DF_DSM in TW_IDENTITY SupportedGroups must use DG_CONTROL DAT_CALLBACK MSG_INVOKE_CALLBACK to return events like MSG_XFERREADY READY.

Memory Management in TWAIN

When TWAIN Applications and Sources must use these memory functions: Memory allocation - NewHandle

Memory free - DisposeHandle

Memory lock - dereference the handle

Memory unlock - is a no op

The Structure of a Source

The following sections describe the structure of a source Implementation

A Source on a Macintosh is implemented as a bundle. The Source will not run standalone. A separate copy of the Source’s code in memory will be made for each application that opens the Source. The bundle must contain a Contents directory and, inside it, an Info plist file. It is recommended that bundle contains universal 32/64 binary. Bundle structure is shown below: See the sample DS - http://twain-samples.svn.sourceforge.net. Naming and Location

The extension for a Source is ds. The Source Manager will search for bundles with this extension in the /Library/Image Capture/TWAIN Data Sources/ directory. It is recommended that each Source bundle contains any other files it may require. Compatibility with Older Data Sources

Pre Mac OS X Data Sources are not compatible with the TWAIN implementation on Mac OS X.

Sources and Handling Events

Do not receive TW_EVENTS from the DSM. On Mac OS X, the Data source uses Cocoa. A Cocoa Data Source gets the UI event handling for free.

Implementing Modal and Modeless User Interfaces

You cannot use the modal dialog creation call DialogBox to create the Source’s user interface main window. To allow event processing by both the application and the Source, this call cannot be used. Modal user interfaces in Source are not inherently bad, however. If a modal user interface makes sense for your Source, use either the CreateDialog or CreateWindow call. When sending MSG_ENABLEDS set hParent to NULL.

Modal (App Modal)

It is recommended that the Source’s main user interface window be created with a modeless mechanism. Source writers can still decide to make their user interface behave modally if they choose. It is even appropriate for a very simple “click and go” interface to be implemented this way. This is done by first specifying setting the ModalUI field to TRUE and second by enabling/ disabling the parent window during the MSG_ENABLEDS MSG_DISABLEDS operations. Use EnableWindow(NULL, FALSE) to disable the window and EnableWindow(NULL, FALSE) to re- enable it. Modeless

If implementing a modeless user interface, set the ModalUI field to FALSE. Also, it is suggested that you call BringWindowToTop whenever a second request is made by the same application or another application requesting access to a Source that supports multiple application connections.

Implementing Modal and Modeless User Interfaces

It is recommended that the Source’s main user interface window be created with a modeless mechanism. Source writers can still decide to make their user interface behave modally if they choose. It is even appropriate for a very simple “click and go” interface to be implemented this way.

Native Transfer Mode

Every Source must support Native transfer mode. It is the default mode and is the easiest for an application to implement, however it is restrictive. If both the application and the data source are TWAIN 2.4 and later: The native format is a TIFF.

Set pHandle pointing to a TIFF file located in memory. The Source will allocate the image buffer and return the handle to the address specified.

If either the application or the data source is TWAIN 2.3 and earlier: The native format is a PICT.

The version of PICT to be transferred is the latest version available on the machine on which the application is running (usually PICT II for machines running 32-bit/color QuickDraw and PICT I for machines running black and white QuickDraw).

Set pHandle pointing to a handle to a Picture in memory. The Source will allocate the image buffer at the memory location referenced by the handle.

Format the data block as a PICT, preferably using standard system calls.

Native Audio format is audio handle ICAP_XNATIVERESOLUTION and ICAP_YNATIVERESOLUTION are required for Mac ImageCaputre to use TWAIN Data Source. These capabilities are not required by TWAIN.

File Transfer

The TW_SETUPFILEXFER pSetupFile >FileName = name of file must only

pSetupFile >VRefNum = The volume reference and folder reference number.

Developing for Linux

Installation of the Data Source Manager

Please check the TWAIN website http://www.twain.org to see if a binary supplied for your distro is represented, and if not, please consider making a submission of one to the TWAIN Working Group. The TWAIN DSM is a shared library named libtwaindsm.so. There is a 32-bit and a 64-bit version of this file. libtwaindsm so location is: /usr/local/lib. For 32-bit DS running on 64-bit system it is: /usr/local/lib32

Load the TWAIN Source Manager and get the DSM_Entry

This process takes a TWAIN application from State 1 to 2. Load TWAINDSM so using the dlopen routine. Get the DSM_Entry by using the dlsym call.

The Source Manager is a shared library.

OpenDSM

To Move from State 2 to State 3 Application must set pParent to NULL

OpenDS

The Source Manager does a dlopen of the Source and sends an OpenDS triplet to the Source.

CloseDS

Checks its internal counter to see whether any other applications are accessing the specified Source. If so, the Source Manager takes no other action. If the closing application is the last to be accessing this Source, the Source Manager closes the Source (forwards this triplet to it) and removes it from memory, following receipt of TWRC_SUCCESS from the Source.

Upon receiving the request from the Source Manager, the Source immediately prepares to terminate execution.

Unload DSM

To Move from State 2 to State 1 Once the Source Manager has been closed, the application must unload the SO from memory before continuing. Use dlclose hDSMLib where hDSMLib is the pointer to the Source Manager SO returned from the call to dlopen seen earlier (in the State 1 to 2 section).

Memory Management in TWAIN

All TWAIN Applications and Sources must use the memory functions supplied by the DSM.

The Structure of a Source

The following sections describe the structure of a source. Implementation

A Source is implemented as a shared library. The Source will not run standalone. A separate copy of the Source’s code will be made for each application that opens the Source. Naming and Location

The extension for a Source is ds. The Source Manager will search for a shared library with this extension in the /usr/local/lib/twain directory. For 32-bit DS running on 64-bit system it is: / usr/local/lib32/twain It is recommended that each Source is placed in its own directory and any other files it may require placed with it.

Implementing Modal and Modeless User Interfaces

It is recommended that the Source’s main user interface window be created with a modeless mechanism. Source writers can still decide to make their user interface behave modally if they choose. It is even appropriate for a very simple “click and go” interface to be implemented this way.

Native Transfer Mode

Every Source must support Native transfer mode. It is the default mode and is the easiest for an application to implement, however it is restrictive and the format is limited to TIFF when implementing on Linux. For Linux, the native format is a TIFF. Set pHandle pointing to a TIFF file located in memory. The Source will allocate the image buffer and return the handle to the address specified. Native Audio format is WAV

File Transfer

The TW_SETUPFILEXFER pSetupFile >FileName = name of file must include the complete path and name

pSetupFile >VRefNum = is not used

Change to TW_INT32 and TW_UINT32 on 64-bit Linux

The TWAIN Specification defines TW_INT and TW_UINT as "long" for Windows and Linux. This is not a problem on Windows, because it follows LLP64, which defines "long" as a 32-bit integer, equivalent to an "int" Linux, however, conforms to LP64, which defines "long" as a 64-bit integer. This means that on 64-bit Linux systems TW_INT and TW_UINT are 64-bit integers. This isn't a problem in terms of TWAIN communication, but it's a serious problem when these data types are used in other operations. Therefore, beginning with the release of version 2.4 of the Data Source Manager, applications, the data source manager, and TWAIN drivers, must all use the version of twain.h that specifies that TW_INT is an "int" and TW_UINT is an "unsigned int". The TWAIN Working Group feels that this move is necessary. It also feels that this move is possible because adoption of TWAIN on 64-bit Linux systems is still in its early stages. There is no intention to try to support systems that mix old drivers with new drivers. This is because older applications and data source managers have no way of knowing about this change or dealing with it, and because the change in the size of structures such as TW_IDENTITY make it likely that programs will crash. 13 TWAIN Self-Certification Process for Data Sources

Chapter Contents

Overview 13-1

Non-Goals of Basic TWAIN Self-Certification 13-2

Affirmation of Successful Completion of TWAIN Self-Certification 13-3

TWAIN “Congratulations” Webpage 13-10

TWAIN Self-Certification Tests 13-10

TWAIN Standard Capability Tests 13-11

Vendor Custom Capability Tests 13-19

Status Return Tests 13-25

Stress Tests 13-27

Non-UI Image Transfer Tests 13-28

UI Image Transfer Tests 13-33

CAP_XFERCOUNT Tests 13-34

Version Tests 13-39

Verify Values For MSG_RESETALL and MSG_RESET 13-41

The TWAIN self-certification system helps developers test their data source’s support of the basic interface described by the TWAIN Specification. Passing the test helps to confirm that the data source’s interface works as expected with applications, leading to a better user experience.

This document provides the Test Plan for TWAIN self-certification for data sources. It also describes how to submit a form affirming successful completion of the test to receive authorization to display the “TWAIN Certified” logo.

Overview

The TWAIN interface operates between an application and a data source. The nature of this interface is described by the TWAIN Specification. Basic TWAIN self-certification exercises specific portions of the TWAIN interface and behavior of the TWAIN interface that all data sources are required to support. Passing these tests confirms that a data source correctly follows the TWAIN Specification, when responding to commands sent by an application, and that it does not crash or hang. This is not a comprehensive test of the entire TWAIN interface. It focuses on enforcing basic “good behavior”. More stringent tests may be described in future. The basic self-certification test is limited to the kinds of checks described in this document. Modifications may be made in association with new versions of the TWAIN Specification (for instance, the addition of a new mandatory feature). For this reason self-certification is always done in the context of a particular version of the TWAIN Specification (ex: 2.2). TWAIN data sources with a protocol version of 1.9 or higher may be self-certified. The version of this document is a measure of the kinds of tests performed on the data source. Running the tests in this document does not certify a TWAIN 1.9 data source as TWAIN 2.2 compliant, rather the data source is self-certified as TWAIN 1.9 compliant using criteria described inside of the TWAIN 2.2 Specification. TWAIN data sources that have been self-certified will work correctly with any compliant TWAIN Application reporting a TWAIN protocol version of 1.5 or higher. TWAIN self-certification promotes the creation of 64-bit applications and data sources by requiring simultaneous submissions of native 32-bit and 64-bit data sources for Windows Vista or later, Macintosh OS X or Linux. A native 64-bit data source is one that interfaces with a native 64- bit application. 64-bit applications cannot be run on 32-bit Systems. A 32-bit data source running in any kind of virtual or thunking environment on a 64-bit Operating System does not qualify as a native 64-bit data source. TWAIN self-certification requires the presence of a TWAIN data source manager corresponding to the version of the TWAIN data source or higher. If one is not pre-installed on the operating system, then the TWAIN data source must install it. Questions or comments regarding TWAIN self-certification should be referred to the TWAIN Forum www.twainforum.org.

Non-Goals of Basic TWAIN Self-Certification

This is a test of the operation of the interface; it does not test the internals of the data source. This test is not designed to catch data errors (ex: bad pointers, data corruption, array out of bounds, etc) except in those instances where the error happens to cause the failure of some other test. Negotiated settings are not confirmed in the meta-data or images they produce (ex: did changing ICAP_BRIGHTNESS really result in a brighter or darker image, was the proper print string written on the document).

Constraints for TW_ENUMERATION and TW_RANGE are not tested (ex: limiting the ICAP_PIXELTYPE enumeration to just TWPT_RGB, or limiting ICAP_BRIGHTNESS to a range of - 100 to 100). Mandatory features for accessories are not tested (ex: there is no check to make sure that all of the barcode features are properly supported if any one barcode capability is detected).

Affirmation of Successful Completion of TWAIN Self- Certification

After TWAIN self-certification has been successfully completed the tester may submit an “Acknowledgement of Successful Completion of TWAIN Self-Certification” form to the TWAIN Working Group. This can be accomplished in more than one way. The preferred method is to access the TWAIN Working Group website (www.twain.org), and access the section titled “Scanner Driver Developers.” Under there is the “Certify TWAIN Driver” link. Alternatively, one can submit a notarized or a digitally signed form of the document This form includes the following information

Company: The name of the company manufacturing the data source being self-certified, a division within that company may be optionally provided. The submitter may also opt to provide a URL to their company’s website which will link off of this name.

Hardware: The model name, model number and revision of the hardware used during self- certification. This is marketing information identifying the device supported by this specific TWAIN data source. In most cases this information can be found printed somewhere on the device.

TWAIN Data Source Identity: Fields from the TWAIN data source’s TW_IDENTITY structure, which indicate the manufacturer, family, product, and the version number, uniquely identify the data source to the application. The TW_IDENTITY ProductName should be unique by itself, since this is the only field displayed by the data source manager’s user select dialog on Windows.

TWAIN Data Source Version: The complete version of the TWAIN data source, matching the .DLL version on Windows, and the .so file name on Linux and Mac OS X, this version number matches the MajorNum and MinorNum fields from the data source’s TW_IDENTITY Version structure.

Installation: The name and the version of the installation media that includes this TWAIN data source provides information the user needs to install the self-certified TWAIN driver.

Operating System: The operating system’s name and revision (version number or service pack) that was used during self-certification.

Processor: The computer processor of the host machine used during self-certification, examples include: x86, x64, IA64. This should match the native processor supported by the TWAIN data source. For example, if the self-certification is performed for a 32-bit TWAIN data source on Windows XP or Linux without a 64-bit data source, then the x86 processor should be used. 32-Bit / 64-Bit: When performing the self-certification test on Windows Vista or later, or any version of Macintosh OS X, or Linux, the submitted form must indicate successful completion using both a native 32-bit and a native 64-bit data source.

Email: The name and email address of a contact. This is initially used to deliver the Logo, but it will also be used to help manage entries posted by the TWAIN Working Group.

URL: The URL to the Installer for the TWAIN data source is a convenience for users browsing the posted list of self-certified content. It is optional, but recommended.

Self-Certification Method: The submitter may specify the software used to perform self- certification, when indicated this information is made available to users browsing the posted list of self-certified content.

It is expected that multiple versions of the same driver will be submitted over the life of the hardware product. Please be aware of the following: Email address: The email address specifies the contact who receives the Logo for a successful submission. This same email address must be used when submitting a new instance of a previously submitted TWAIN data source, or when replacing an existing submission. Requests using other email addresses may not be recognized by the TWAIN Working Group.

Signature: There is no requirement for the same signature (notarized or digital) to be used from one submission to the next, but pairing the same signature with the same email address for all submissions for a given driver is appreciated.

Hardware: The model name and model number uniquely identifies the hardware supported by the TWAIN data source. Submissions of new TWAIN data sources for the same hardware must take care to make sure that this information is identical from one version to the next. If there is no exact match with an existing hardware entry, then the entire entry is treated as new.

TWAIN Data Source Identity: The following fields uniquely identify the TWAIN data source: TW_IDENTITY Manufacturer, TW_IDENTITY ProductFamily and TW_IDENTITY ProductName. When updating a previously existing self-certified TWAIN data source it is important to make sure this data is identical from one version to the next. If there is no exact match with an existing TWAIN data source, then the entire entry is treated as new.

TWAIN Data Source Version: Many vendors use a four field versioning system (ex: 1.2.0.1). The first two fields must correspond to the TW_IDENTITY Info Version Major and TW_IDENTITY Info Version Minor fields. The last two fields vary among vendors, and are not described here. The value zero must be used for any unused field. If a submission has exactly the same email, hardware, data source and version information as a previous submission, it will replace its posting on the TWAIN Working Group website. If there is no exact match with an existing TWAIN data source, then the entire entry is treated as new.

Operating System: The operating system’s name and revision (version number or service pack) that was used during self-certification. If there is no exact match with an existing TWAIN data source, then the entire entry is treated as new.

The TWAIN Working Group makes no attempt to enforce continuity of versions. If the submission is correct, the version numbers may change in any way specified by the submitter.

Submission of the form qualifies the data source and its associated hardware to display the TWAIN Certified Logo. Submission information from the form is displayed on the TWAIN Working Group website (www.twain.org). Contact information is required to deliver the Logo; this includes the name of a contact and an email address. This information will not be shared or made public. The form asks if the email

address may be used to occasionally send information relating to TWAIN or the TWAIN Working Group. The form must be either digitally signed or notarized. This identification is meant to guarantee that the document has not been modified since it was signed. The form includes an address where it can be mailed as a paper copy or emailed. The complete form is on the next two pages.

Form

Affirmation of Successful Completion of TWAIN Self-Certification Compliance with TWAIN Versions 1.9 through 2.2 Page 1 of 2 Completion and submission of a digitally signed or notarized original of this statement to the TWAIN Working Group authorizes the authorized representative or their company to display the TWAIN Certified Logo on the hardware, software and marketing materials of the TWAIN data source described below. All fields must be filled in, except where otherwise indicated. The certification mark is intended for use by authorized entities or persons and is intended to certify that this software conforms to standards designated by the TWAIN Working Group. This document indicates compliance with the TWAIN Specification for version TWAIN 2.2 or earlier. The following information will not be published or shared. The Logo will be sent to the email address. Name of Contact:

Email Address:

May the TWAIN Working Group send TWAIN information not related to this submissionto this email address? (circle one) [Yes] [No]

The following fields will be posted on the TWAIN Working Group website.

Company:

Division: (optional) Company/Division URL: (optional) Hardware Model Name: Hardware Model Number: Hardware Model Revision: (optional) TW_IDENTITY.Manufacturer: TW_IDENTITY.ProductFamily: TW_IDENTITY.ProductName: TW_IDENTITY.Protocol: TWAIN Data Source Version: Installer Version: URL to Data Source: (optional) .

. . .

Processor: x86

Operating System/Revision:

Self-Certification Software: (optional)

x64

other

Vendor Custom Capability Tests Status Return Tests Stress Tests

Non-UI Image Transfer Tests UI Image Transfer Tests CAP_XFERCOUNT

Version Tests My commission expires: Notary Public Signature SS Subscribed and duly sworn in my presence this day of 20 . Country of State of Printed Name Date Signature of Authorized Representative I attest under penalty of perjury to the fact that the information on this form is true and accurate.

Mail the Notarized Document to:

The TWAIN Working Group 7960 Soquel Drive B113 Aptos, Ca. 95003

- or -

Email the Digitally Signed Document to: admin@twain.org

Sample Form

Affirmation of Successful Completion of TWAIN Self-Certification Compliance with TWAIN Versions 1.9 through 2.2 Page 1 of 2 S A M P L E Completion and submission of a digitally signed or notarized original of this statement to the TWAIN Working Group authorizes the authorized representative or their company to display the TWAIN Certified Logo on the hardware, software and marketing materials of the TWAIN data source described below. All fields must be filled in, except where otherwise indicated. The certification mark is intended for use by authorized entities or persons and is intended to certify that this software conforms to standards designated by the TWAIN Working Group. This document indicates compliance with the TWAIN Specification for version TWAIN 2.2 or earlier. The following information will not be published or shared. The Logo will be sent to the email address. Name of Contact: John Smith

Email Address: twainselfcert@notarealcompany.com

May the TWAIN Working Group send TWAIN information not related to this submissionto this email address? (circle one) [Yes] [No]

The following fields will be posted on the TWAIN Working Group website.

Company: Not A Real Company Division: (optional) Scanner Group Company/Division URL: (optional) www.notarealcompany.com/scanners Hardware Model Name: Business Scanner Hardware Model Number: 123

Hardware Model Revision: (optional) 6.0

TW_IDENTITY.Manufacturer: Not A Real Company TW_IDENTITY.ProductFamily: Business Scanner TW_IDENTITY.ProductName: Not A Real Scanner: 123 TW_IDENTITY.Protocol: TWAIN Data Source Version: 2 . 1

5 . 3 . 0 . 0 Installer Version: Not A Real Scanner: 123, CD v3.4.0.0

URL to Data Source: (optional) www.notarealcompany.com/scanners/123 Processor: x86 _x_ x64 _x_ other Operating System/Revision: Windows Vista / SP2 Self-Certification Software: (optional) Inspector TWAIN 3.1.14 X X Vendor Custom Capability Tests X X Status Return Tests X X Stress Tests X X Non-UI Image Transfer Tests X X UI Image Transfer Tests X X CAP_XFERCOUNT X X Version Tests My commission expires: Notary Public Signature SS Subscribed and duly sworn in my presence this day of 20 . Country of State of Printed Name Date Signature of Authorized Representative I attest under penalty of perjury to the fact that the information on this form is true and accurate. S A M P L E

Mail the Notarized Document to:

The TWAIN Working Group 7960 Soquel Drive B113 Aptos, Ca. 95003

- or -

Email the Digitally Signed Document to: admin@twain.org

TWAIN “Congratulations” Webpage

Applications that automate the TWAIN self-certification process are asked to use the “Congratulations” web page to complete the process. Hard coding the “Affirmation of Successful Completion of TWAIN Self-Certification” may require updates to the application if the TWAIN Working Group changes the document. Use of the web page avoids this problem. The URL of the web page is: http://www.twain.org/self_certification_congratulations.shtm

TWAIN Self-Certification Tests

The tests are broken down into the following groups: TWAIN Standard Capability Tests Exercise DAT_CAPABILITY operations for all standard TWAIN capabilities reported by CAP_SUPPORTEDCAPS. Confirm use of containers and supported operations.

Vendor Custom Capability Tests Exercise DAT_CAPABILITY operations for any vendor spe- cific custom capabilities reported by CAP_SUPPORTEDCAPS.

Status Return Tests Confirm that the expected status return is reported by cer- tain operations.

Stress Tests Stress aspects of data sources that have been reported as common problems.

Non-UI Image Transfer Tests Confirm that multiple MSG_ENABLEDS and MSG_DIS- ABLEDS calls can be made in the context of one MSG_OPENDS / MSG_CLOSEDS. This test focuses on image capture with no UI.

UI Image Transfer Tests Confirm that multiple MSG_ENABLEDS and MSG_DIS- ABLEDS calls can be made in the context of one MSG_OPENDS / MSG_CLOSEDS. This test focuses on image capture with the UI.

ICAP_XFERMECH Test the ability of the data source to transfer the correct number of images based on the value of ICAP_XFERMECH.

Version Test Confirm that the data sources responds correctly to differ- ent TWAIN versions of data source manager and applica- tion.

TWAIN Standard Capability Tests

Purpose

Exercise all of the TWAIN Standard capabilities exposed by CAP_SUPPORTEDCAPS using the standard operations supported by DG_CONTROL DAT_CAPABILITY. Operations on capabilities (MSG_ values specified below) are assumed to be DG_CONTROL DAT_CAPABILITY, unless otherwise stated.

Pre-Test Procedure

Open the data source manager. It is required that when opened the data source is in the state it would be in after being installed (e.g., no saved settings from previous sessions), to make the test more reproducible. When performing this test on Windows Vista or later, Macintosh OS X or Linux it must be successfully completed using both a native 32-bit and a native 64-bit data source.

Confirm Basic Negotiation with CAP_SUPPORTEDCAPS

Make sure that CAP_SUPPORTEDCAPS is working properly. Perform basic checks on how well it supports negotiation. Action: MSG_GET CAP_SUPPORTEDCAPS (get the list of capabilities to be tested)

Test: If result is not TWRC_SUCCESS, then end with error

Test: If TW_CAPABILITY Cap is not CAP_SUPPORTEDCAPS, then end with error

Test: If TW_CAPABILITY ConType is not TWON_ARRAY, then end with error

Test: If TW_CAPABILITY hContainer is not a valid TW_HANDLE value, then end with error

Test: If TW_ARRAY ItemType is not TWTY_UINT , then end with error

Test: If TW_ARRAY NumItems is equal to zero, then end with error

Action: Confirm the presence of the following capabilities in TW_ARRAY ItemList

Test: If CAP_SUPPORTEDCAPS not found, then end with error

Test: If ICAP_PIXELTYPE not found, then end with error

Test: If ICAP_XFERMECH not found, then end with error

Confirm Basic Negotiation with ICAP_PIXELTYPE

Make sure that ICAP_PIXELTYPE is working properly. Perform basic checks on how well it supports negotiation. Action: MSG_GET ICAP_PIXELTYPE

Test: If result is not TWRC_SUCCESS, then end with error

Test: If TW_CAPABILITY Cap is not ICAP_PIXELTYPE, then end with error

Test: If TW_CAPABILITY ConType is not TWON_ENUMERATION, then end with error

Test: If TW_CAPABILITY hContainer is not a valid TW_HANDLE value, then end with error

Test: If TW_ENUMERATION ItemType is not TWTY_UINT , then end with error

Test: If TW_ENUMERATION NumItems is equal to zero, then end with error

Confirm Basic Negotiation with ICAP_BITDEPTH

Make sure that ICAP_BITDEPTH is working properly, and doesn’t include invalid values for commonly used pixel types. Action: MSG_SET ICAP_PIXELTYPE to TWPT_BW

Test: If result is not TWRC_SUCCESS, then proceed to the TWPT_GRAY test immediately below

Action: MSG_GET ICAP_BITDEPTH

Test: If TW_CAPABILITY ConType is not TWON_ENUMERATION, then proceed to the TWPT_RGB test below

Test: If TW_CAPABILITY hContainer is not a valid TW_HANDLE value, then end with error

Test: If TW_ENUMERATION ItemType is not TWTY_UINT , then end with error

Test: If the TW_ENUMERATION ItemList includes a value of , then end with error

Action: MSG_SET ICAP_PIXELTYPE to TWPT_GRAY

Test: If result is not TWRC_SUCCESS, then proceed to the TWPT_RGB test below

Action: MSG_GET ICAP_BITDEPTH

Test: If TW_CAPABILITY ConType is not TWON_ENUMERATION, then proceed to the TWPT_RGB test below

Test: If TW_CAPABILITY hContainer is not a valid TW_HANDLE value, then end with error

Test: If TW_ENUMERATION ItemType is not TWTY_UINT , then end with error

Test: If the TW_ENUMERATION ItemList includes a value of , then end with error

Test: If the TW_ENUMERATION ItemList includes a value of , then end with error

Action: MSG_SET ICAP_PIXELTYPE to TWPT_RGB

Test: If result is not TWRC_SUCCESS, then proceed to the next test section

Action: MSG_GET ICAP_BITDEPTH

Test: If TW_CAPABILITY ConType is not TWON_ENUMERATION, then proceed to the TWPT_RGB test below

Test: If TW_CAPABILITY hContainer is not a valid TW_HANDLE value, then end with error

Test: If TW_ENUMERATION ItemType is not TWTY_UINT , then end with error

Test: If the TW_ENUMERATION ItemList includes a value of , then end with error

Confirm Basic Negotiation with ICAP_XFERMECH

Make sure that ICAP_XFERMECH is working properly. Perform basic checks on how well it supports negotiation. Action: MSG_GET ICAP_XFERMECH

Test: If result is not TWRC_SUCCESS, then end with error

Test: If TW_CAPABILITY Cap is not ICAP_XFERMECH, then end with error

Test: If TW_CAPABILITY ConType is not TWON_ENUMERATION, then end with error

Test: If TW_CAPABILITY hContainer is not a valid TW_HANDLE value, then end with error

Test: If TW_ENUMERATION ItemType is not TWTY_UINT , then end with error

Test: If TW_ENUMERATION NumItems is less than two, then end with error

Exercise DAT_CAPABILITY

Exercise DAT_CAPABILITY operations for all TWAIN Standard capabilities (ID’s with a value less than 0x8000). Ignore Vendor Custom capabilities (ID’s with a value of 0x8000 or greater). Confirm correct ConType and ItemType values described in the TWAIN Specification in the chapter titled Chapter 10, "Capabilities". Action: MSG_RESETALL

Test: If return code is not TWRC_SUCCESS, end with an error

Action: Repeat this section for each enumerated value found inside of ICAP_PIXELTYPE, (testing is done for each value of ICAP_PIXELTYPE, to provide the best chance of exercising every available capability)

Action: Repeat this section for Standard TWAIN array values found inside of CAP_SUPPORTEDCAPS (each Standard TWAIN capability ID is referred to as #CAP# for the rest of this section) Action: MSG_QUERYSUPPORT CAP 7.3.1.1. Test: If result is not TWRC_SUCCESS, then end with error 7.3.1.2. Test: If TW_CAPABILITY Cap is not CAP , then end with error 7.3.1.3. Test: If TW_CAPABILITY ConType is not TWON_ONEVALUE, then end with error 7.3.1.4. Test: If TW_ONEVALUE ItemType is not TWTY_UINT , then end with error 7.3.1.5. Test: If TW_CAPABILITY hContainer is not a valid TW_HANDLE value, then end with error 7.3.1.6. Test: If the value of TW_ONEVALUE Item doesn’t match the TWQC values for this capability, then end with error 7.3.1.7. Test: If TWQC_GET, TWQC_GETCURRENT or TWQC_GETDEFAULT is detected, then all three must be present, if any are missing end with error 7.3.1.8. Test: If TWQC_RESET or TWQC_SET is detected, then both must be present, plus TWQC_GET, TWQC_GETCURRENT and TWQC_GETDEFAULT, if not true then end with error 7.3.2. Action: If TWQC_GET is reported, then call MSG_GET CAP 7.3.2.1. Test: If result is TWRC_FAILURE / TWCC_CAPSEQERROR, then skip to the next capability 7.3.2.2. Test: If result is not TWRC_SUCCESS, then end with error 7.3.2.3. Test: If TW_CAPABILITY Cap is not CAP , then end with error 7.3.2.4. Test: If TW_CAPABILITY hContainer is not a valid TW_HANDLE value, then end with error 7.3.2.5. Test: If the value of TW_CAPABILITY ConType doesn’t match the Specification’s MSG_GET container for this capability, then end with error 7.3.2.6. Test: If container’s ItemType doesn’t match the Specification’s ItemType for this capability, then end with error 7.3.3. Action: If TWQC_GETCURRENT is reported, then call MSG_GETCURRENT CAP 7.3.3.1. Test: If result is not TWRC_SUCCESS, then end with error 7.3.3.2. Test: If TW_CAPABILITY Cap is not CAP , then end with error 7.3.3.3. Test: If TW_CAPABILITY hContainer is not a valid TW_HANDLE value, then end with error

Action: If TWQC_GET was reported by MSG_QUERYSUPPORT then do the following: Test: If the TW_CAPABILITY ConType for MSG_GET was TWON_ENUMERATION, TWON_ONEVALUE or TWON_RANGE, then the TW_CAPABILITY ConType for MSG_GETCURRENT must be TWTY_ONEVALUE, if not then end with error Test: If the TW_CAPABILITY ConType for MSG_GET was TWON_ARRAY then the TW_CAPABILITY ConType for MSG_GETCURRENT must be TWTY_ARRAY, if not then end with error Test: If container’s ItemType for MSG_GET doesn’t match container’s ItemType for MSG_GETCURRENT, then end with error Action: If TWQC_GETDEFAULT is reported, then call MSG_GETDEFAULT CAP

Test: If result is not TWRC_SUCCESS, then end with error Test: If TW_CAPABILITY Cap is not CAP , then end with error Test: If TW_CAPABILITY hContainer is not a valid TW_HANDLE value, then end with error Action: If TWQC_GET was reported by MSG_QUERYSUPPORT then do the following: Test: If the TW_CAPABILITY ConType for MSG_GET was TWON_ENUMERATION, TWON_ONEVALUE or TWON_RANGE, then the TW_CAPABILITY ConType for MSG_GETDEFAULT must be TWTY_ONEVALUE, if not then end with error Test: If the TW_CAPABILITY ConType for MSG_GET was TWON_ARRAY then the TW_CAPABILITY ConType for MSG_GETDEFAULT must be TWTY_ARRAY, if not then end with error Test: If container’s ItemType for MSG_GET doesn’t match container’s ItemType for MSG_GETDEFAULT, then end with error Action: If TWQC_RESET is reported, then call MSG_RESET CAP

Test: If result is not TWRC_SUCCESS, then end with error Test: If TW_CAPABILITY Cap is not CAP , then end with error Test: If TW_CAPABILITY hContainer is not a valid TW_HANDLE value, then end with error Action: If TWQC_GET was reported by MSG_QUERYSUPPORT then do the following:

Test: If TW_CAPABILITY ConType for MSG_GET doesn’t match TW_CAPABILITY ConType for MSG_RESET, then end with error Test: If container’s ItemType for MSG_GET doesn’t match container’s ItemType for MSG_RESET, then end with error Action: If TWQC_SET is reported then do the following:

Action: If TWQC_GET was reported by MSG_QUERYSUPPORT then do the following: Action: MSG_GET CAP Test: If result is not TWRC_SUCCESS, then end with error Action: MSG_SET with TW_CAPABILITY from MSG_GET Test: If result is TWRC_FAILURE / TWCC_CAPSEQERROR, then skip to next capability Test: If result is not TWRC_SUCCESS or TWRC_CHECKSTATUS, then end with error Action: If TWQC_GETCURRENT was reported by MSG_QUERYSUPPORT then do the following: Action: MSG_GETCURRENT CAP Test: If result is not TWRC_SUCCESS, then end with error Action: MSG_SET with TW_CAPABILITY from MSG_GETCURRENT Test: If result is TWRC_FAILURE / TWCC_CAPSEQERROR, then skip to next capability Test: If result is not TWRC_SUCCESS or TWRC_CHECKSTATUS, then end with error Action: If TWQC_GETDEFAULT was reported by MSG_QUERYSUPPORT then do the following: Action: MSG_GETDEFAULT CAP Test: If result is not TWRC_SUCCESS, then end with error

Action: MSG_SET with TW_CAPABILITY from

MSG_GETDEFAULT Test: If result is TWRC_FAILURE / TWCC_CAPSEQERROR, then skip to next capability Test: If result is not TWRC_SUCCESS or TWRC_CHECKSTATUS, then end with error Action: If TWQC_RESET was reported by MSG_QUERYSUPPORT then do the following: Action: MSG_RESET CAP Test: If result is not TWRC_SUCCESS, then end with error Action: MSG_SET with TW_CAPABILITY from

MSG_RESET Test: If result is TWRC_FAILURE / TWCC_CAPSEQERROR, then skip to next capability Test: If result is not TWRC_SUCCESS, then end with error Action: If TWQC_GET was reported by MSG_QUERYSUPPORT then do the following: Action: MSG_GET CAP Test: If result is not TWRC_SUCCESS, then end with error Test: If the container’s ItemType is TWTY_BOOL and the test application has DF_APP in its TW_IDENTITY SupportedGroups, and the data source has DF_DS in its TW_IDENTITY SupportedGroups, then TW_CAPABILITY ConType must be set to TW_ENUMERATION, if not then end with error Test: If the container’s ItemType is TWTY_BOOL and the test application does not have DF_APP in its TW_IDENTITY SupportedGroups, or the data source does not have DF_DS in its TW_IDENTITY SupportedGroups, then TW_CAPABILITY ConType must be set to TW_ONEVALUE, if not then end with error Action: If TW_CAPABILITY ConType is TWON_ARRAY then repeat following for each value in the array: Action: MSG_SET the value using a TW_ARRAY container Test: If result is not TWRC_SUCCESS or TWRC_CHECKSTATUS, then end with error Action: If TW_CAPABILITY ConType is TWON_ARRAY then do the following: Action: MSG_SET the value using a TW_ARRAY container, setting the value to 22222 (which is expected to be an illegal value) Test: If result is not TWRC_BADVALUE or TWRC_CHECKSTATUS, then end with error Action: If TW_CAPABILITY ConType is TWON_ENUMERATION then repeat following for each value in the enumeration: Action: MSG_SET the value using a TW_ENUMERATION container Test: If result is not TWRC_SUCCESS or TWRC_CHECKSTATUS, then end with error Action: If TW_CAPABILITY ConType is TWON_ENUMERATION then do the following: Action: MSG_SET the current value using a TW_ONEVALUE container, the value must be something that did not appear in the list of valid enumerations Test: If result is not TWRC_BADVALUE, then end with error Action: If TW_CAPABILITY ConType is TWON_RANGE then repeat the following for the TW_RANGE MinValue, TW_RANGE CurrentValue and TW_RANGE MaxValue: Action: MSG_SET the current value using a TW_RANGE container

Test: If result is not TWRC_SUCCESS or TWRC_CHECKSTATUS, then end with error

Post-Test Procedure

When testing is completed, close the data source and the data source manager.

Vendor Custom Capability Tests

Purpose

Exercise all of the Vendor Custom capabilities exposed by CAP_SUPPORTEDCAPS using the standard operations supported by DG_CONTROL DAT_CAPABILITY. Operations on capabilities (MSG_ values specified below) are assumed to be DG_CONTROL DAT_CAPABILITY, unless otherwise stated.

Pre-Test Procedure

Open the data source manager and the data source that is to be tested. It is recommended that the data source is in the state it would be in after being installed (e.g., no saved settings from previous sessions), to make the test more reproducible. When performing this test on Windows Vista or later, Macintosh OS X or Linux it must be successfully completed using both a native 32-bit and a native 64-bit data source.

Confirm Basic Negotiation with CAP_SUPPORTEDCAPS

Make sure that CAP_SUPPORTEDCAPS is working properly. Perform basic checks on how well it supports negotiation. Action: MSG_RESETALL

Test: If return code is not TWRC_SUCCESS, end with an error

Action: MSG_GET CAP_SUPPORTEDCAPS (gets the list of capabilities to be tested)

Test: If result is not TWRC_SUCCESS, then end with error

Test: If TW_CAPABILITY Cap is not CAP_SUPPORTEDCAPS, then end with error

Test: If TW_CAPABILITY ConType is not TWON_ARRAY, then end with error

Test: If TW_CAPABILITY hContainer is not a valid TW_HANDLE value, then end with error

Test: If TW_ARRAY ItemType is not TWTY_UINT , then end with error Test: If TW_ARRAY NumItems is equal to zero, then end with error

Action: Confirm the presence of the following capabilities in

TW_ARRAY ItemList

Test: If CAP_SUPPORTEDCAPS not found, then end with error Test: If ICAP_PIXELTYPE not found, then end with error

Confirm Basic Negotiation with ICAP_PIXELTYPE

Make sure that ICAP_PIXELTYPE is working properly. Perform basic checks on how well it supports negotiation. Action: MSG_GET ICAP_PIXELTYPE

Test: If result is not TWRC_SUCCESS, then end with error

Test: If TW_CAPABILITY Cap is not ICAP_PIXELTYPE, then end with error

Test: If TW_CAPABILITY ConType is not TWON_ENUMERATION, then end with error

Test: If TW_CAPABILITY hContainer is not a valid TW_HANDLE value, then end with error

Test: If TW_ENUMERATION ItemType is not TWTY_UINT , then end with error

Test: If TW_ENUMERATION NumItems is equal to zero, then end with error

Exercise DAT_CAPABILITY

Exercise DAT_CAPABILITY operations for all Vendor Custom capabilities (ID’s with a value of x or greater). Ignore TWAIN Standard capabilities (ID’s with a value less than x ). Action: Repeat this section for each enumerated value found inside of ICAP_PIXELTYPE, (testing is done for each value of ICAP_PIXELTYPE, to provide the best chance of exercising every available capability)

Action: Repeat this section for each Vendor Custom TWAIN array value found inside of CAP_SUPPORTEDCAPS (each Vendor Custom capability ID is referred to as CAP for the rest of this section)

Action: MSG_QUERYSUPPORT CAP

Test: If result is not TWRC_SUCCESS, then end with error Test: If TW_CAPABILITY Cap is not CAP , then end with error Test: If TW_CAPABILITY ConType is not TWON_ONEVALUE, then end with error Test: If TW_ONEVALUE ItemType is not TWTY_UINT , then end with error Test: If TW_CAPABILITY hContainer is not a valid TW_HANDLE value, then end with error

Action: If TWQC_GET is reported, then call MSG_GET CAP

Test: If result is TWRC_FAILURE TWCC_CAPSEQERROR, then skip to the next capability Test: If result is not TWRC_SUCCESS, then end with error Test: If TW_CAPABILITY Cap is not CAP , then end with error Test: If TW_CAPABILITY hContainer is not a valid TW_HANDLE value, then end with error Action: If TWQC_GETCURRENT is reported, then call MSG_GETCURRENT CAP

Test: If result is not TWRC_SUCCESS, then end with error Test: If TW_CAPABILITY Cap is not CAP , then end with error Test: If TW_CAPABILITY hContainer is not a valid TW_HANDLE value, then end with error Action: If TWQC_GET was reported by MSG_QUERYSUPPORT then do the following: Test: If the TW_CAPABILITY ConType for MSG_GET was TWON_ENUMERATION, TWON_ONEVALUE or TWON_RANGE, then the TW_CAPABILITY ConType for MSG_GETCURRENT must be TWTY_ONEVALUE, if not then end with error Test: If the TW_CAPABILITY ConType for MSG_GET was TWON_ARRAY then the TW_CAPABILITY ConType for MSG_GETCURRENT must be TWTY_ARRAY, if not then end with error Test: If container’s ItemType for MSG_GET doesn’t match container’s ItemType for MSG_GETCURRENT, then end with error Action: If TWQC_GETDEFAULT is reported, then call MSG_GETDEFAULT CAP

Test: If result is not TWRC_SUCCESS, then end with error Test: If TW_CAPABILITY Cap is not CAP , then end with error Test: If TW_CAPABILITY hContainer is not a valid TW_HANDLE value, then end with error Action: If TWQC_GET was reported by MSG_QUERYSUPPORT then do the following: Test: If the TW_CAPABILITY ConType for MSG_GET was TWON_ENUMERATION, TWON_ONEVALUE or TWON_RANGE, then the TW_CAPABILITY ConType for MSG_GETDEFAULT must be TWTY_ONEVALUE, if not then end with error Test: If the TW_CAPABILITY ConType for MSG_GET was TWON_ARRAY then the TW_CAPABILITY ConType for MSG_GETDEFAULT must be TWTY_ARRAY, if not then end with error Test: If container’s ItemType for MSG_GET doesn’t match container’s ItemType for MSG_GETDEFAULT, then end with error Action: If TWQC_RESET is reported, then call MSG_RESET CAP

Test: If result is not TWRC_SUCCESS, then end with error Test: If TW_CAPABILITY Cap is not CAP , then end with error Test: If TW_CAPABILITY hContainer is not a valid TW_HANDLE value, then end with error Action: If TWQC_GET was reported by MSG_QUERYSUPPORT then do the following: Test: If TW_CAPABILITY ConType for MSG_GET doesn’t match TW_CAPABILITY ConType for MSG_RESET, then end with error Test: If container’s ItemType for MSG_GET doesn’t match container’s ItemType for MSG_RESET, then end with error Action: If TWQC_SET is reported then do the following:

Action: If TWQC_GET was reported by MSG_QUERYSUPPORT then do the following: Action: MSG_GET CAP Test: If result is not TWRC_SUCCESS, then end with error Action: MSG_SET with TW_CAPABILITY from MSG_GET Test: If result is TWRC_FAILURE TWCC_CAPSEQERROR, then skip to next capability Test: If result is not TWRC_SUCCESS or TWRC_CHECKSTATUS, then end with error

Action: If TWQC_GETCURRENT was reported by MSG_QUERYSUPPORT then do the following: Action: MSG_GETCURRENT CAP Test: If result is not TWRC_SUCCESS, then end with error Action: MSG_SET with TW_CAPABILITY from

MSG_GETCURRENT Test: If result is TWRC_FAILURE / TWCC_CAPSEQERROR, then skip to next capability Test: If result is not TWRC_SUCCESS or TWRC_CHECKSTATUS, then end with error Action: If TWQC_GETDEFAULT was reported by MSG_QUERYSUPPORT then do the following: Action: MSG_GETDEFAULT CAP Test: If result is not TWRC_SUCCESS, then end with error Action: MSG_SET with TW_CAPABILITY from

MSG_GETDEFAULT Test: If result is TWRC_FAILURE TWCC_CAPSEQERROR, then skip to next capability Test: If result is not TWRC_SUCCESS or TWRC_CHECKSTATUS, then end with error Action: If TWQC_RESET was reported by MSG_QUERYSUPPORT then do the following: Action: MSG_RESET CAP Test: If result is not TWRC_SUCCESS, then end with error Action: MSG_SET with TW_CAPABILITY from

MSG_RESET Test: If result is TWRC_FAILURE TWCC_CAPSEQERROR, then skip to next capability Test: If result is not TWRC_SUCCESS, then end with error Action: If TWQC_GET was reported by MSG_QUERYSUPPORT then do the following: Action: MSG_GET CAP Test: If result is not TWRC_SUCCESS, then end with error Test: If the container’s ItemType is TWTY_BOOL and the test application has DF_APP in its TW_IDENTITY SupportedGroups, and the data source has DF_DS in its TW_IDENTITY SupportedGroups, then TW_CAPABILITY ConType must be set to TW_ENUMERATION, if not then end with error Test: If the container’s ItemType is TWTY_BOOL and the test application does not have DF_APP in its TW_IDENTITY SupportedGroups, or the data source does not have DF_DS in its TW_IDENTITY SupportedGroups, then TW_CAPABILITY ConType must be set to TW_ONEVALUE, if not then end with error Action: If TW_CAPABILITY ConType is TWON_ARRAY then repeat following for each value in the array: Action: MSG_SET the value using a TW_ARRAY container Test: If result is not TWRC_SUCCESS or TWRC_CHECKSTATUS, then end with error Action: If TW_CAPABILITY ConType is TWON_ARRAY then do the following: Action: MSG_SET the value using a TW_ARRAY container, setting the value to 22222 (which is expected to be an illegal value) Test: If result is not TWRC_BADVALUE or TWRC_CHECKSTATUS, then end with error Action: If TW_CAPABILITY ConType is TWON_ENUMERATION then repeat following for each value in the enumeration:

Action: MSG_SET the value using a TW_ENUMERATION container Test: If result is not TWRC_SUCCESS or TWRC_CHECKSTATUS, then end with error Action: If TW_CAPABILITY ConType is TWON_ENUMERATION then do the following: Action: MSG_SET the current value using a TW_ONEVALUE container, the value must be something that did not appear in the list of valid enumerations Test: If result is not TWRC_BADVALUE, then end with error Action: If TW_CAPABILITY ConType is TWON_RANGE then repeat the following for the TW_RANGE MinValue, TW_RANGE CurrentValue and TW_RANGE MaxValue: Action: MSG_SET the current value using a TW_RANGE container Test: If result is not TWRC_SUCCESS or TWRC_CHECKSTATUS, then end with error

Post-Test Procedure

When testing is completed, close the data source and the data source manager.

Status Return Tests

Purpose

Confirm that the expected status return is reported by certain operations. This is not an exhaustive test of all possible Status Returns.

Pre-Test Procedure

Open the data source manager and the data source that is to be tested. It is recommended that the data source is in the state it would be in after being installed (e.g., no saved settings from previous sessions), to make the test more reproducible. When performing this test on Windows Vista or later, Macintosh OS X or Linux it must be successfully completed using both a native 32-bit and a native 64-bit data source.

Check Status Returns for DAT_IMAGENATIVEXFER and DAT_IMAGEMEMXFER

Confirm that DAT_IMAGENATIVEXFER and DAT_IMAGEMEMXFER both return the correct status returns in various error conditions. Action: In State 4 (after MSG_OPENDS, but before calling MSG_ENABLEDS)…

Confirm that the proper statuses are returned for bad protocols and attempts to perform image transfers in State 4.

Action: Call DG_IMAGE DAT_IMAGENATIVEXFER MSG_SET

Test: If result is not TWRC_FAILURE TWCC_BADPROTOCOL, then end with error

Action: Call DG_IMAGE DAT_IMAGENATIVEXFER MSG_GET

Test: If result is not TWRC_FAILURE TWCC_SEQERROR, then end with error

Action: Call DG_IMAGE DAT_IMAGEMEMXFER MSG_SET

Test: If result is not TWRC_FAILURE TWCC_BADPROTOCOL, then end with error

Action: Call DG_IMAGE DAT_IMAGEMEMXFER MSG_GET

Test: If result is not TWRC_FAILURE TWCC_SEQERROR, then end with error

Check Status Returns for DAT_IMAGELAYOUT

Confirm that DAT_IMAGELAYOUT returns the correct status returns in various error conditions. Action: Call DG_CONTROL DAT_USERINTERFACE MSG_ENABLEDS with ShowUI TRUE

Test: If result is not TWRC_SUCCESS, then end with error

Action: Call DG_IMAGE DAT_IMAGELAYOUT MSG_GET

Test: If result is not TWRC_SUCCESS, then end with error

Action: Call DG_IMAGE DAT_IMAGELAYOUT MSG_SET using the TW_IMAGELAYOUT values from the previous MSG_GET call

Test: If result is not TWRC_FAILURE TWRC_SEQERROR, then end with error

Action: Call DG_IMAGE DAT_IMAGELAYOUT MSG_RESET

Test: If result is not TWRC_FAILURE TWCC_SEQERROR, then end with error

Check Status Returns for DAT_CAPABILITY

Confirm that DAT_CAPABILITY returns the correct status returns in various error conditions.

Action: Call DG_CONTROL DAT_USERINTERFACE MSG_ENABLEDS with ShowUI TRUE

Test: If result is not TWRC_SUCCESS, then end with error

Action: MSG_GET CAP_SUPPORTEDCAPS

Test: If result is not TWRC_SUCCESS, then end with error

Action: MSG_GET CAP_EXTENDEDCAPS

Test: If result is not TWRC_SUCCESS or the TW_ARRAY is empty, then skip any checks of CAP_EXTENDEDCAPS referenced in the rest of this section

Action: For each value found in CAP_SUPPORTEDCAPS that is not in CAP_EXTENDEDCAPS do the following sections (each capability ID is referred to as CAP for the rest of this section):

Action: MSG_GET CAP

Test: If result is not TWRC_SUCCESS, then skip to next capability Action: MSG_SET CAP with results of previous MSG_GET

Test: If result is TWRC_SUCCESS or TWRC_CHECKSTATUS, then end with error Action: MSG_RESET CAP

Test: If result is TWRC_SUCCESS or TWRC_CHECKSTATUS, then end with error

Post-Test Procedure

When testing is completed, close the data source and the data source manager.

Stress Tests

Purpose

Stress aspects of data sources that have been reported as common problems.

Pre-Test Procedure

Open the data source manager. It is required that when opened the data source is in the state it would be in after being installed (e.g., no saved settings from previous sessions), to make the test more reproducible. When performing this test on Windows Vista or later, Macintosh OS X or Linux it must be successfully completed using both a native 32-bit and a native 64-bit data source.

Open and Close the Data Source Multiple Times

Confirm that the data source can open and close multiple times. This tests for crashes. Action: Repeat this section twenty (20) times

Confirm that the data source can successfully open and close repeated times from a single instance of an application.

Action: Call DG_CONTROL DAT_IDENTITY MSG_OPENDS

Test: If result is not TWRC_SUCCESS, then end with error

Action: Call DG_CONTROL DAT_IDENTITY MSG_CLOSEDS

Test: If result is not TWRC_SUCCESS, then end with error

Post-Test Procedure

When testing is completed, close the data source and the data source manager.

Non-UI Image Transfer Tests

Purpose

Confirm that multiple MSG_ENABLEDS and MSG_DISABLEDS calls can be made in the context of one MSG_OPENDS MSG_CLOSEDS. This test focuses on image capture with no UI, verifying that the Application does not have to close the driver after capturing images.

Pre-Test Procedure

Open the data source manager and the data source that is to be tested. It is recommended that the data source is in the state it would be in after being installed (e.g., no saved settings from previous sessions), to make the test more reproducible. When performing this test on Windows Vista or later, Macintosh OS X or Linux it must be successfully completed using both a native 32-bit and a native 64-bit data source.

Exercise DAT_IMAGENATIVEXFER

This test issues multiple image transfer sessions using DAT_IMAGENATIVEXFER. It is performed for all available image sources (unspecified, flatbed and/or ADF). Only one image is transferred per session. Action: MSG_RESETALL

Test: If return code is not TWRC_SUCCESS, end with an error

Action: MSG_GET CAP_SUPPORTEDCAPS (get the list of capabilities to be tested)

Action: MSG_SET ICAP_XFERMECH to TWSX_NATIVE

Action: MSG_GETCURRENT ICAP_XFERMECH

Test: If return code is not TWRC_SUCCESS, end with an error

Test: If value is not TWSX_NATIVE, end with an error.

Action: If CAP_FEEDERENABLED is TRUE, set CAP_AUTOFEED to TRUE

Action: MSG_SET CAP_DUPLEXENABLED to FALSE

Action: MSG_SET CAP_XFERCOUNT to

Action: Do the following for each supported ICAP_PIXELTYPE

Action: MSG_SET ICAP_PIXELTYPE

Action: MSG_GET ICAP_BITDEPTH

Action: Do the following for each supported ICAP_BITDEPTH

Action: MSG_SET ICAP_BITDEPTH Action: Do the following for the minimum, maximum and 300 (or nearest) resolution values. Action: MSG_SET ICAP_XRESOLUTION and

ICAP_YRESOLUTION Action: DG_CONTROL DAT_USERINTERFACE MSG_ENABLEDS with ShowUI FALSE and ModalUI FALSE Test: If return code is not TWRC_SUCCESS, end with an error Action: Wait for MSG_XFERREADY Action: MSG_GET ICAP_XFERMECH Test: If return code is not TWRC_SUCCESS, end with an error Action: DG_IMAGE DAT_IMAGENATIVEXFER MSG_GET Test: If return code is not TWRC_XFERDONE, end with an error Test: If the handle does not point to a valid image, end with an error Test: If the bit depth of the image is not what was requested, end with an error Action: Free handle returned by

DAT_IMAGENATIVEXFER

Action: DG_CONTROL DAT_PENDINGXFERS MSG_ENDXFER Action: DG_CONTROL DAT_USERINTERFACE MSG_DISABLEDS Test: If return code is not TWRC_SUCCESS, end with an error

Exercise DAT_IMAGEMEMXFER

This test issues multiple image transfer sessions using DAT_IMAGEMEMXFER. It is performed for all available image sources (unspecified, flatbed and/or ADF). Only one image is transferred per session. The preferred size specified by the data source is used to transfer each strip. Action: MSG_RESETALL

Test: If return code is not TWRC_SUCCESS, end with an error

Action: MSG_SET ICAP_XFERMECH to TWSX_MEMORY

Action: MSG_GETCURRENT ICAP_XFERMECH

Test: If return code is not TWRC_SUCCESS, end with an error

Test: If value is not TWSX_MEMORY, end with an error

Action: If CAP_FEEDERENABLED is TRUE, set CAP_AUTOFEED to TRUE

Action: MSG_SET CAP_DUPLEXENABLED to FALSE

Action: MSG_SET CAP_XFERCOUNT to

Action: Do the following for each supported ICAP_PIXELTYPE

Action: MSG_SET ICAP_PIXELTYPE

Action: MSG_GET ICAP_BITDEPTH

Action: Do the following for each supported ICAP_BITDEPTH

Action: MSG_SET ICAP_BITDEPTH Action: MSG_GET ICAP_COMPRESSION Action: Do the following for each supported ICAP_COMPRESSION Action: MSG_SET ICAP_COMPRESSION Action: Do the following for the minimum, maximum and 300 (or nearest) resolution values. Action: MSG_SET ICAP_XRESOLUTION and ICAP_YRESOLUTION

Action: DG_CONTROL

DAT_USERINTERFACE MSG_ENABLEDS with ShowUI FALSE and ModalUI FALSE Test: If return code is not TWRC_SUCCESS, end with an error Action: Wait for MSG_XFERREADY Action: MSG_GET ICAP_XFERMECH Test: If return code is not TWRC_SUCCESS, end with an error Action: DG_CONTROL

DAT_SETUPMEMXFER MSG_GET Test: If return code is not TWRC_SUCCESS, end with an error Action: DG_IMAGE DAT_IMAGEMEMXFER MSG_GET with the preferred buffer size Test: if the return code is TWRC_SUCCESS, repeat previous step Test: if the return code is not TWRC_XFERDONE, end with an error Action: DG_CONTROL

DAT_PENDINGXFERS MSG_ENDXFER Action: DG_CONTROL

DAT_USERINTERFACE MSG_DISABLEDS Test: If return code is not TWRC_SUCCESS, end with an error

Exercise DAT_IMAGEFILEXFER

This test issues multiple image transfer sessions using DAT_IMAGEFILEXFER. It is performed for all available image sources (unspecified, flatbed and/or ADF). Only one image is transferred per session. The preferred size specified by the data source is used to transfer each strip. Action: MSG_RESETALL

Test: If return code is not TWRC_SUCCESS, end with an error

Action: MSG_SET ICAP_XFERMECH to TWSX_MEMORY

Test: If return code is TWRC_SUCCESS TWCC_BADVALUE, skip to section 4 Test: If return code is not TWRC_SUCCESS, end with an error

Action: MSG_SET ICAP_XFERMECH to TWSX_FILE

Action: If CAP_FEEDERENABLED is TRUE, set CAP_AUTOFEED to TRUE

Action: MSG_SET CAP_DUPLEXENABLED to FALSE

Action: MSG_SET CAP_XFERCOUNT to

Action: MSG_GET ICAP_IMAGEFILEFORMAT

Action: Do the following for each supported ICAP_IMAGEFILEFORMAT

Action: MSG_SET ICAP_IMAGEFILEFORMAT

Action: MSG_GET ICAP_PIXELTYPE

Action: Do the following for each supported ICAP_PIXELTYPE

Action: MSG_SET ICAP_PIXELTYPE Action: MSG_GET ICAP_BITDEPTH Action: Do the following for each supported ICAP_BITDEPTH Action: MSG_SET ICAP_BITDEPTH Action: MSG_GET ICAP_COMPRESSION Action: Do the following for each supported

ICAP_COMPRESSION Action: MSG_SET ICAP_COMPRESSION Action: Do the following for the minimum, maximum and 300 (or nearest) resolution values. Action: MSG_SET ICAP_XRESOLUTION and

ICAP_YRESOLUTION Action: DG_CONTROL

DAT_USERINTERFACE MSG_ENABLEDS with ShowUI FALSE and ModalUI FALSE Test: If return code is not TWRC_SUCCESS, end with an error Action: Wait for

MSG_XFERREADY

Action: MSG_GET

ICAP_XFERMECH Test: If return code is not TWRC_SUCCESS, end with an error Action: DG_CONTROL

DAT_SETUPFILEXFER MSG_SET Action: DG_IMAGE

DAT_IMAGEFILEXFER MSG_GET Test: If return code is not TWRC_XFERDONE, end with an error Action: DG_CONTROL

DAT_PENDINGXFERS MSG_ENDXFER Action: DG_CONTROL

DAT_USERINTERFACE MSG_DISABLEDS Test: If return code is not TWRC_SUCCESS, end with an error

Post-Test Procedure

When testing is completed, close the data source and the data source manager.

UI Image Transfer Tests

Purpose

Confirm that multiple MSG_ENABLEDS and MSG_DISABLEDS calls can be made in the context of one MSG_OPENDS MSG_CLOSEDS. This test focuses on image capture with the UI, verifying that the Application does not have to close the driver after capturing images.

Procedure

These tests are identical to the “Non-UI Image Transfer Tests”, except that the value of ShowUI is set to TRUE instead of FALSE. When performing this test on Windows Vista or later, Macintosh OS X or Linux it must be successfully completed using both a native 32-bit and a native 64-bit data source.

CAP_XFERCOUNT Tests

Purpose

Confirm that when the data source accepts various values for CAP_XFERCOUNT, that it returns the specified number of images. Test both flatbed and document feeders.

Pre-Test Procedure

Open the data source manager and the data source that is to be tested. It is recommended that the data source is in the state it would be in after being installed (e.g., no saved settings from previous sessions), to make the test more reproducible. When performing this test on Windows Vista or later, Macintosh OS X or Linux it must be successfully completed using both a native 32-bit and a native 64-bit data source.

Test Flatbed Scanning

This test sets CAP_XFERCOUNT to , and for a flatbed scanner. It expects an error for the value , and only one image to be transferred per scanning session for the values and . Action: MSG_RESETALL

Test: If return code is not TWRC_SUCCESS, end with an error

Action: MSG_SET CAP_FEEDERENABLED to FALSE

Test: If return is TWRC_FAILURE TWCC_BADVALUE, then scanner does not have a flatbed, proceed to the Test Document Feeder Scanning section

Test: If return is not TWRC_SUCCESS and not TWRC_FAILURE TWCC_CAPUNSUPPORTED, end with error

Action: MSG_SET ICAP_XFERMECH to TWSX_NATIVE

Test: If return is not TWRC_SUCCESS, end with error

Action: MSG_SET CAP_XFERCOUNT to

Test: If return code is not TWRC_FAILURE TWCC_BADVALUE, end with an error

Action: MSG_SET CAP_XFERCOUNT to

Test: If return is not TWRC_SUCCESS, end with error

Action: DG_CONTROL DAT_USERINTERFACE MSG_ENABLEDS with ShowUI FALSE and ModalUI FALSE

Test: If return code is not TWRC_SUCCESS, end with an error

Action: Wait for MSG_XFERREADY

Action: DG_IMAGE DAT_IMAGENATIVEXFER MSG_GET

Test: If return code is not TWRC_XFERDONE, end with an error

Action: DG_CONTROL DAT_PENDINGXFERS MSG_ENDXFER

Test: If return code is not TWRC_SUCCESS, end with an error

Test: If TW_PENDINGXFERS Count is not , end with error

Action: DG_CONTROL DAT_USERINTERFACE MSG_DISABLEDS

Test: If return code is not TWRC_SUCCESS, end with an error

Action: MSG_SET CAP_XFERCOUNT to

Test: If return is not TWRC_SUCCESS, end with error

Action: DG_CONTROL DAT_USERINTERFACE MSG_ENABLEDS with ShowUI FALSE and ModalUI FALSE

Test: If return code is not TWRC_SUCCESS, end with an error

Action: Wait for MSG_XFERREADY

Action: DG_IMAGE DAT_IMAGENATIVEXFER MSG_GET

Test: If return code is not TWRC_XFERDONE, end with an error

Action: DG_CONTROL DAT_PENDINGXFERS MSG_ENDXFER

Test: If return code is not TWRC_SUCCESS, end with an error

Test: If TW_PENDINGXFERS Count is not , end with error

Action: DG_CONTROL DAT_USERINTERFACE MSG_DISABLEDS

Test: If return code is not TWRC_SUCCESS, end with an error

Test Document Feeder Scanning

This test issues multiple image transfer sessions using DAT_IMAGENATIVEXFER. It is performed for all available image sources (unspecified, flatbed and/or ADF). Only one image is transferred per session. Action: MSG_RESETALL

Test: If return code is not TWRC_SUCCESS, end with an error

Action: MSG_SET CAP_FEEDERENABLED to TRUE

Test: If return is TWRC_FAILURE TWCC_BADVALUE or TWRC_FAILURE TWCC_CAPUNSUPPORTED, then scanner does not have a Document Feeder, skip the rest of this section Test: If return is not TWRC_SUCCESS, end with error

Action: MSG_SET ICAP_XFERMECH to TWSX_NATIVE

Test: If return is not TWRC_SUCCESS, end with error

Action: MSG_SET CAP_XFERCOUNT to

Test: If return is not TWRC_SUCCESS or TWRC_CHECKSTATUS, end with error

Action: MSG_GET CAP_XFERCOUNT

Test: If return is not TWRC_SUCCESS, end with error

Test: If value is not equal to do this section

Action: MSG_SET CAP_XFERCOUNT to Test: If return code is not TWRC_FAILURE TWCC_BADVALUE, end with an error Action: MSG_SET CAP_XFERCOUNT to Test: If return is not TWRC_SUCCESS, end with error Action: Ask user to place one sheet of paper in the document feeder DG_CONTROL DAT_USERINTERFACE MSG_ENABLEDS with ShowUI FALSE and ModalUI FALSE Test: If return code is not TWRC_SUCCESS, end with an error Action: Wait for MSG_XFERREADY Action: DG_IMAGE DAT_IMAGENATIVEXFER MSG_GET Test: If return code is not TWRC_XFERDONE, end with an error Action: DG_CONTROL DAT_PENDINGXFERS MSG_ENDXFER Test: If return code is not TWRC_SUCCESS, end with an error Test: If TW_PENDINGXFERS Count is not , end with error Action: DG_CONTROL DAT_USERINTERFACE MSG_DISABLEDS Test: If return code is not TWRC_SUCCESS, end with an error Action: MSG_SET CAP_XFERCOUNT to

Test: If return is not TWRC_SUCCESS, end with error Action: Ask user to place one sheet of paper in the document feeder Action: DG_CONTROL DAT_USERINTERFACE MSG_ENABLEDS with ShowUI FALSE and ModalUI FALSE Test: If return code is not TWRC_SUCCESS, end with an error Action: Wait for MSG_XFERREADY Action: DG_IMAGE DAT_IMAGENATIVEXFER MSG_GET Test: If return code is not TWRC_XFERDONE, end with an error Action: DG_CONTROL DAT_PENDINGXFERS MSG_ENDXFER Test: If return code is not TWRC_SUCCESS, end with an error Test: If TW_PENDINGXFERS Count is not , end with error Action: DG_CONTROL DAT_USERINTERFACE MSG_DISABLEDS Test: If return code is not TWRC_SUCCESS, end with an error Test: If value is equal to do this section

Action: Ask user to place three sheets of paper in the document feeder Action: MSG_SET CAP_DUPLEXENABLED to FALSE Test: If return code is not TWRC_SUCCESS or TWRC_FAILURE TWCC_CAPUNSUPPORTED, end with error Action: MSG_SET CAP_XFERCOUNT to Test: If return code is not TWRC_FAILURE TWCC_BADVALUE, end with an error Action: MSG_SET CAP_XFERCOUNT to Test: If return is not TWRC_SUCCESS, end with error Action: DG_CONTROL DAT_USERINTERFACE MSG_ENABLEDS with ShowUI FALSE and ModalUI FALSE

Test: If return code is not TWRC_SUCCESS, end with an error Action: Wait for MSG_XFERREADY Action: DG_IMAGE DAT_IMAGENATIVEXFER MSG_GET Test: If return code is not TWRC_XFERDONE, end with an error Action: DG_CONTROL DAT_PENDINGXFERS MSG_ENDXFER Test: If return code is not TWRC_SUCCESS, end with an error Test: If TW_PENDINGXFERS Count is not , end with error Action: DG_CONTROL DAT_USERINTERFACE MSG_DISABLEDS Test: If return code is not TWRC_SUCCESS, end with an error Action: MSG_SET CAP_XFERCOUNT to Test: If return is not TWRC_SUCCESS, end with error Action: DG_CONTROL DAT_USERINTERFACE MSG_ENABLEDS with ShowUI FALSE and ModalUI FALSE Test: If return code is not TWRC_SUCCESS, end with an error Action: Wait for MSG_XFERREADY Action: DG_IMAGE DAT_IMAGENATIVEXFER MSG_GET Test: If return code is not TWRC_XFERDONE, end with an error Action: DG_CONTROL DAT_PENDINGXFERS MSG_ENDXFER Test: If return code is not TWRC_SUCCESS, end with an error Test: If TW_PENDINGXFERS Count is not or , end with error Action: DG_IMAGE DAT_IMAGENATIVEXFER MSG_GET Test: If return code is not TWRC_XFERDONE, end with an error

Action: DG_CONTROL DAT_PENDINGXFERS MSG_ENDXFER Test: If return code is not TWRC_SUCCESS, end with an error Test: If TW_PENDINGXFERS Count is not , end with error Action: DG_CONTROL DAT_USERINTERFACE MSG_DISABLEDS Test: If return code is not TWRC_SUCCESS, end with an error

Post-Test Procedure

When testing is completed, close the data source and the data source manager.

Version Tests

Purpose

Confirm that the data sources responds correctly to different TWAIN versions of data source manager and application.

Pre-Test Procedure

Close the data source manager.

Attempt to scan Multiple Times

Confirm that the data source can respond correctly to different TWAIN version of application and data source manager by attempting to scan using different setups. This tests for hangs and crashes. Use Memory transfer if available. Scan one image in simplex without UI. Testing with old DSM is only for 32-bit data sources only. Action: MSG_OPENDSM using old DSM as TWAIN version 1.9 application, with DF_APP set,

Action: Attempt to scan

Test: Confirm that the scan succeeds without hanging.

Test: If the application does not receive MSG_XFERREADY, then end with error

Action: MSG_CLOSEDSM

Action: MSG_OPENDSM using old DSM as TWAIN version 2.x application, with DF_APP not set,

Action: Attempt to scan Test: Confirm that the scan succeeds without hanging.

Test: If the application does not receive MSG_XFERREADY, then end with error

Action: MSG_CLOSEDSM

Action: MSG_OPENDSM using old DSM as TWAIN version 2.x application, with DF_APP set,

Action: Attempt to scan

Test: Confirm that the scan succeeds without hanging.

Test: If the application does not receive MSG_XFERREADY, then end with error

Action: MSG_CLOSEDSM

Action: MSG_OPENDSM using TWAIN 2 DSM as TWAIN version 1.9 application, with DF_APP set,

Action: Attempt to scan

Test: Confirm that the scan succeeds without hanging.

Test: If the application does not receive MSG_XFERREADY, then end with error

Action: MSG_CLOSEDSM

Action: MSG_OPENDSM using TWAIN 2 DSM as TWAIN version 2.x application, with DF_APP not set,

Action: Attempt to scan

Test: Confirm that the scan succeeds without hanging.

Test: If the application does not receive MSG_XFERREADY, then end with error

Action: MSG_CLOSEDSM

Action: MSG_OPENDSM using TWAIN 2 DSM as TWAIN version 1.9 application, with DF_APP not set,

Action: Attempt to scan

Test: Confirm that the scan succeeds without hanging.

Test: If the application does not receive MSG_XFERREADY, then end with error

Action: MSG_CLOSEDSM

Post-Test Procedure

Nothing to do.

Verify Values For MSG_RESETALL and MSG_RESET

Purpose

Confirm that the indicated capabilities have the values required by the Specification after a DG_CONTROL DAT_CAPABILITY MSG_RESETALL is applied to the entire driver, or a DG_CONTROL DAT_CAPABILITY MSG_RESET is applied to a single capability.

Pre-Test Procedure

Open the data source manager and the data source that is to be tested.

Test MSG_RESETALL and MSG_RESET

Make sure that MSG_RESETALL results in the following values for the indicated capabilities. Action: DG_CONTROL DAT_CAPABILITY MSG_RESETALL

Test: If result is not TWRC_SUCCESS, then end with error

Action: MSG_GETCURRENT ACAP_XFERMECH

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWSX_NATIVE, then end with error

Action: MSG_RESET ACAP_XFERMECH

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWSX_NATIVE, then end with error Action: MSG_GETCURRENT CAP_AUTHOR

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_STRING , or the value is not an empty string, then end with error

Action: MSG_RESET CAP_AUTHOR

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_STRING , or the value is not an empty string, then end with error Action: MSG_GETCURRENT CAP_AUTOFEED

Test: If result is not TWRC_SUCCESS, then skip down to the next capability Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not TRUE, then end with error

Action: MSG_RESET CAP_AUTOFEED

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not TRUE, then end with error Action: MSG_GETCURRENT CAP_AUTOMATICCAPTURE

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_INT , or the value is not , then end with error

Action: MSG_RESET CAP_AUTOMATICCAPTURE

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_INT , or the value is not , then end with error Action: MSG_GETCURRENT CAP_CAMERSIDE

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWCS_BOTH, then end with error

Action: MSG_RESET CAP_CAMERSIDE

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWCS_BOTH, then end with error Action: MSG_GETCURRENT CAP_CAPTION

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_STRING , or the value is not an empty string, then end with error

Action: MSG_RESET CAP_CAPTION

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_STRING , or the value is not an empty string, then end with error Action: MSG_GETCURRENT CAP_CLEARPAGE

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error

Action: MSG_RESET CAP_CLEARPAGE

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error Action: MSG_GETCURRENT CAP_DEVICEEVENT

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ARRAY, or the value is not an empty array, then end with error

Action: MSG_RESET CAP_DEVICEEVENT

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ARRAY, or the value is not an empty array, then end with error Action: MSG_GETCURRENT CAP_DOUBLEFEEDDETECTION

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ARRAY, or the value is not an empty array, then end with error

Action: MSG_RESET CAP_DOUBLEFEEDDETECTION

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ARRAY, or the value is not an empty array, then end with error Action: MSG_GETCURRENT CAP_ENDORSER

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not , then end with error

Action: MSG_RESET CAP_ENDORSER

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not , then end with error Action: MSG_GETCURRENT CAP_FEEDERPREP

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error Action: MSG_RESET CAP_FEEDERPREP

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error Action: MSG_GETCURRENT CAP_FEEDPAGE

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error

Action: MSG_RESET CAP_FEEDPAGE

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error Action: MSG_GETCURRENT CAP_INDICATORS

Test: If the result is not TWRC_SUCCESS, then end with error

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not TRUE, then end with error

Action: MSG_RESET CAP_INDICATORS

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not TRUE, then end with error Action: MSG_GETCURRENT CAP_INDICATORS

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not TRUE, then end with error

Action: MSG_RESET CAP_INDICATORS

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not TRUE, then end with error Action: MSG_GETCURRENT CAP_JOBCONTROL

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWJC_NONE, then end with error

Action: MSG_RESET CAP_JOBCONTROL

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWJC_NONE, then end with error Action: MSG_GETCURRENT CAP_MICRENABLED

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error

Action: MSG_RESET CAP_MICRENABLED

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error Action: MSG_GETCURRENT CAP_PAPERHANDLING

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWPH_NORMAL, then end with error

Action: MSG_RESET CAP_PAPERHANDLING

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWPH_NORMAL, then end with error Action: MSG_GETCURRENT CAP_PRINTERENABLED

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error

Action: MSG_RESET CAP_PRINTERENABLED

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error Action: MSG_GETCURRENT CAP_PRINTERINDEX

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not , then end with error

Action: MSG_RESET CAP_PRINTERINDEX

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not , then end with error Action: MSG_GETCURRENT CAP_REACQUIREALLOWED

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error

Action: MSG_RESET CAP_REACQUIREALLOWED

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error Action: MSG_GETCURRENT CAP_SEGMENTED

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWSG_NONE, then end with error

Action: MSG_RESET CAP_SEGMENTED

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWSG_NONE, then end with error Action: MSG_GETCURRENT CAP_TIMEBEFOREFIRSTCAPTURE

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_INT , or the value is not , then end with error

Action: MSG_RESET CAP_TIMEBEFOREFIRSTCAPTURE

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_INT , or the value is not , then end with error Action: MSG_GETCURRENT CAP_TIMEBETWEENCAPTURES

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_INT , or the value is not , then end with error

Action: MSG_RESET CAP_TIMEBETWEENCAPTURES

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_INT , or the value is not , then end with error

Action: MSG_GETCURRENT CAP_THUMBNAILSENABLED

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error

Action: MSG_RESET CAP_THUMBNAILSENABLED

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error Action: MSG_GETCURRENT CAP_XFERCOUNT

Test: If result is not TWRC_SUCCESS, then end with error

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_INT , or the value is not , then end with error

Action: MSG_RESET CAP_XFERCOUNT

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_INT , or the value is not , then end with error Action: MSG_GETCURRENT ICAP_AUTOBRIGHT

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error

Action: MSG_RESET ICAP_AUTOBRIGHT

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error Action: MSG_GETCURRENT ICAP_AUTODISCARDBLANKPAGES

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWBP_DISABLE, then end with error

Action: MSG_RESET ICAP_AUTODISCARDBLANKPAGES

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWBP_DISABLE, then end with error Action: MSG_GETCURRENT ICAP_AUTOMATICCOLORENABLED

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error

Action: MSG_RESET ICAP_AUTOMATICCOLORENABLED

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error Action: MSG_GETCURRENT ICAP_AUTOMATICCOLORNONCOLORPIXELTYPE

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWPT_BW, then end with error

Action: MSG_RESET ICAP_AUTOMATICCOLORNONCOLORPIXELTYPE

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWPT_BW, then end with error Action: MSG_GETCURRENT ICAP_AUTOMATICROTATE

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error

Action: MSG_RESET ICAP_AUTOMATICROTATE

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error Action: MSG_GETCURRENT ICAP_AUTOSIZE

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWAS_NONE, then end with error

Action: MSG_RESET ICAP_AUTOSIZE

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWAS_NONE, then end with error Action: MSG_GETCURRENT ICAP_BARCODEDETECTIONENABLED

Test: If result is not TWRC_SUCCESS, then skip down to the next capability or the value is not FALSE, then end with error

Action: MSG_RESET ICAP_BARCODEDETECTIONENABLED

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error 1.35 Action: MSG_GETCURRENT ICAP_BITORDER

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWBO_MSBFIRST, then end with error

Action: MSG_RESET ICAP_BITORDER

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWBO_MSBFIRST, then end with error Action: MSG_GETCURRENT ICAP_BITORDERCODES

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWBO_LSBFIRST, then end with error

Action: MSG_RESET ICAP_BITORDERCODES

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWBO_LSBFIRST, then end with error Action: MSG_GETCURRENT ICAP_BRIGHTNESS

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_FIX , or the value is not , then end with error

Action: MSG_RESET ICAP_BRIGHTNESS

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_FIX , or the value is not , then end with error Action: MSG_GETCURRENT ICAP_CCITTKFACTOR

Test: If result is not TWRC_SUCCESS, then skip down to the next capability Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not , then end with error

Action: MSG_RESET ICAP_CCITTKFACTOR

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not , then end with error Action: MSG_GETCURRENT ICAP_COLORMANAGEMENTENABLED

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not TRUE, then end with error

Action: MSG_RESET ICAP_COLORMANAGEMENTENABLED

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not TRUE, then end with error Action: MSG_GETCURRENT ICAP_COMPRESSION

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWCP_COMPRESSION, then end with error

Action: MSG_RESET ICAP_COMPRESSION

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWCP_COMPRESSION, then end with error Action: MSG_GETCURRENT ICAP_CONTRAST

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_FIX , or the value is not , then end with error

Action: MSG_RESET ICAP_CONTRAST

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_FIX , or the value is not , then end with error Action: MSG_GETCURRENT ICAP_EXTIMAGEINFO

Test: If result is not TWRC_SUCCESS, then skip down to the next capability or the value is not TRUE, then end with error

Action: MSG_RESET ICAP_EXTIMAGEINFO

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not TRUE, then end with error Action: MSG_GETCURRENT ICAP_FILTER

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ARRAY, or the value is not an empty array, then end with error

Action: MSG_RESET ICAP_FILTER

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ARRAY, or the value is not an empty array, then end with error Action: MSG_GETCURRENT ICAP_FLIPROTATION

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWFR_BOOK, then end with error

Action: MSG_RESET ICAP_FLIPROTATION

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWFR_BOOK, then end with error Action: MSG_GETCURRENT ICAP_GAMMA

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_FIX , or the value is not , then end with error

Action: MSG_RESET ICAP_GAMMA

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_FIX , or the value is not , then end with error Action: MSG_GETCURRENT ICAP_HIGHLIGHT

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_FIX , or the value is not , then end with error Action: MSG_REEST ICAP_HIGHLIGHT

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_FIX , or the value is not , then end with error Action: MSG_GETCURRENT ICAP_IMAGEMERGE

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWIM_NONE, then end with error

Action: MSG_RESET ICAP_IMAGEMERGE

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWIM_NONE, then end with error Action: MSG_GETCURRENT ICAP_IMAGEMERGEHEIGHTTHRESHOLD

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_FIX , or the value is not , then end with error

Action: MSG_GETCURRENT ICAP_IMAGEMERGEHEIGHTTHRESHOLD

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_FIX , or the value is not , then end with error Action: MSG_GETCURRENT ICAP_MIRROR

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWMR_NONE, then end with error

Action: MSG_RESET ICAP_MIRROR

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWMR_NONE, then end with error Action: MSG_GETCURRENT ICAP_ORIENTATION

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWOR_PORTRAIT, then end with error

Action: MSG_RESET ICAP_ORIENTATION

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWOR_PORTRAIT, then end with error Action: MSG_GETCURRENT ICAP_OVERSCAN

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWOV_NONE, then end with error

Action: MSG_RESET ICAP_OVERSCAN

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWOV_NONE, then end with error Action: MSG_GETCURRENT ICAP_PATCHCODEDETECTIONENABLED

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error

Action: MSG_RESET ICAP_PATCHCODEDETECTIONENABLED

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error Action: MSG_GETCURRENT ICAP_PIXELFLAVOR

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWPF_CHOCOLATE, then end with error

Action: MSG_RESET ICAP_PIXELFLAVOR

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWPF_CHOCOLATE, then end with error Action: MSG_GETCURRENT ICAP_PIXELFLAVORCODES

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWPF_CHOCOLATE, then end with error

Action: MSG_RESET ICAP_PIXELFLAVORCODES

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWPF_CHOCOLATE, then end with error Action: MSG_GETCURRENT ICAP_ROTATION

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_FIX , or the value is not , then end with error

Action: MSG_RESET ICAP_ROTATION

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_FIX , or the value is not , then end with error Action: MSG_GETCURRENT ICAP_SHADOW

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_FIX , or the value is not , then end with error

Action: MSG_RESET ICAP_SHADOW

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_FIX , or the value is not , then end with error Action: MSG_GETCURRENT ICAP_THRESHOLD

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_FIX , or the value is not , then end with error

Action: MSG_RESET ICAP_THRESHOLD

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_FIX , or the value is not , then end with error Action: MSG_GETCURRENT ICAP_TILES

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error

Action: MSG_RESET ICAP_TILES

Test: If result is not TWRC_SUCCESS, then end with error

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error Action: MSG_GETCURRENT ICAP_TIMEFILL

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not , then end with error

Action: MSG_RESET ICAP_TIMEFILL

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not , then end with error Action: MSG_GETCURRENT ICAP_UNDEFINEDIMAGESIZE

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error

Action: MSG_RESET ICAP_UNDEFINEDIMAGESIZE

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_BOOL, or the value is not FALSE, then end with error Action: MSG_GETCURRENT ICAP_UNITS

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWUN_INCHES, then end with error

Action: MSG_RESET ICAP_UNITS

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not TWUN_INCHES, then end with error Action: MSG_GETCURRENT ICAP_XFERMECH

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not , then end with error

Action: MSG_RESET ICAP_XFERMECH

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_UINT , or the value is not , then end with error Action: MSG_GETCURRENT ICAP_XSCALING

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_FIX , or the value is not , then end with error

Action: MSG_RESET ICAP_XSCALING

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_FIX , or the value is not , then end with error Action: MSG_GETCURRENT ICAP_YSCALING

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_FIX , or the value is not , then end with error

Action: MSG_RESET ICAP_YSCALING

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_FIX , or the value is not , then end with error Action: MSG_GETCURRENT ICAP_ZOOMFACTOR

Test: If result is not TWRC_SUCCESS, then skip down to the next capability

Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_INT , or the value is not , then end with error

Action: MSG_RESET ICAP_ZOOMFACTOR

Test: If result is not TWRC_SUCCESS, then end with error Test: If the container is not TW_ONEVALUE, or the data type is not TWTY_INT , or the value is not , then end with error A TWAIN Articles

Chapter Contents

Device Events A-1

Supported Sizes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A-5

Automatic Capture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A-7

File System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A-11

Internationalization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A-19

Audio Snippets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A-26

How to use the Preview Device . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A-28

Imprinter / Endorser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A-30

Capability Ordering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A-31

Defaults . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A-43

The articles in this appendix provide additional information about some of the features described in this specification.

Device Events

TWAIN 1.8 expands upon asynchronous event notification. Previous versions provided the DG_CONTROL DAT_NULL messages: MSG_CLOSEDSOK, MSG_CLOSEDSREQ and MSG_XFERREADY to permit the Source to alert the Application that it needed to exit, or that an image was ready to be processed. With the addition of Digital Cameras, and the burgeoning interest in Push Technologies, it has become desirable to enhance TWAIN in this area. An event begins when the Source needs to alert the Application to some change that has occurred within the device. For example, the owner of a Digital Camera (which is tethered to a host machine) has changed the setting for flash from on to off. The Source wants to alert the Application of this change: first, it records the event in a FIFO queue; second, it sends a DG_CONTROL DAT_NULL DAT_DEVICEEVENT to the Source Manager, which forwards the message to the Application. The Application receives the DG_CONTROL / DAT_NULL / MSG_DEVICEEVENT, and immediately issues a DG_CONTROL / DAT_DEVICEEVENT / MSG_GET request to the Source. The Source delivers the information about the event, and pops it off the queue. The process concludes with the Application examining the information and acting upon it, in this case by alerting the user that the flash setting on the camera has been changed. Notes:

Sources must start up in a mode with device events turned off (an empty array for CAP_DEVICEEVENTS), this is for the benefit of pre-1.8 applications which may not be able to process this new event.

Device events are never generated by an Application setting a value within a Source (such as Application changing ICAP_FLASHUSED ). Device events are only generated in response to some outside change within the Source or the Device (such as the User changing the flash setting on the camera).

Sources must maintain an internal Event Queue, so that they can report each and every device event to the Application in the order of their occurrence.

Device events are supported in State 4. Windows Sources must use the main window handle supplied with the DG_CONTROL / DAT_PARENT / MSG_OPENDS if they issue device events in State 4. In States 5 through 7 Sources must use the pTW_USERINTERFACE >hParent supplied in the DG_CONTROL / DAT_USERINTERFACE / MSG_ENABLEDS triplet.

Since device events may occur in State 4, Applications that enable them using CAP_DEVICEEVENTS must be ready to receive and process them.

When the Application receives a device event, it must immediately collect the information about it. The Application must not issue the DG_CONTROL / DAT_DEVICEEVENT / MSG_GET, except when it has received a DG_CONTROL / DAT_NULL / MSG_DEVICEEVENT message.

The Application must process events without User intervention, this is to prevent situations where the device event queue builds up because a User is not responding to the system.

Applications may sometimes fail to respond to a Source’s device events. A maximum queue size should be selected so that the Source does not exhaust memory. If the queue fills, the Source must do the following:

Turns off device events (resets CAP_DEVICEEVENT to an empty array).

Refuse to set CAP_DEVICEEVENT until the queue is emptied, return TWCC_SEQERROR.

Process DG_CONTROL / DAT_DEVICEEVENT / MSG_GET requests for each item on the device event queue.

After the last device event is read by the Application, return TWRC_FAILURE / TWCC_DEVICEEVENTOVERFLOW for the next call to DG_CONTROL / DAT_DEVICEEVENT / MSG_GET. After TWCC_DEVICEEVENTOVERFLOW has been reported, permit the Source to set CAP_DEVICEEVENT again. Flash Display: ON OFF Flash ON Source Source Application Event Queue Manager Flash OFF Step 1: The Source senses that the device has changed from ON to OFF and stores this information in an Event Queue. A Queue must be used because the Source may generate multiple events before the Application can respond. Flash Display: OFF Flash ON Step 2: The Source sends a DG_CONTROL / DAT_NULL / MSG_DEVICEEVENT to the Application. The Application only knows that some Event has taken place. Flash Display: OFF Flash ON Source DG_CONTROL/ Source Application Event Queue DAT_DEVICEEVENT Manager MSG_GET Flash Flash OFF OFF Step 3: The Application sends a DG_CONTROL / DAT_DEVICEEVENT / MSG_GET to the Source to learn about the Event. The Source informs the Application that the flash is OFF and it clears the Event from its Queue. Flash Display: OFF Flash OFF Source Source Application Event Queue Manager (empty) Flash OFF Step 4: The Application informs the User that the flash is now OFF. Source Event Queue Flash OFF Source Application Manager DG_CONTROL / DAT_NULL / MSG_DEVICEEVENT

Figure A-1 Device Events This section details the various event types and how Sources and Applications should make use of them. TWDE_CHECKAUTOMATICCAPTURE

The automatic capture settings on the device have been changed.

TWDE_CHECKBATTERY

Status of the battery has changed. Sources will report BatteryMinutes or BatteryPercentage depending on which capabilities say they support.

TWDE_CHECKDEVICEONLINE

The device has been powered off. If an Application receives this device event, it should call CAP_DEVICEONLINE to verify the state of the Source, and then proceed as seems appropriate.

TWDE_CHECKFLASH

The flash setting on the device has been changed.

TWDE_CHECKPOWERSUPPLY

The power supply has changed, for example this event would be generated if AC was removed from a device, putting it on battery. Scanners may also provide this event to notify that a power on reset has taken place, indicating that the device has been power cycled.

TWDE_CHECKRESOLUTION

The resolution on the device has changed.

TWDE_DEVICEADDED

A device has been added to the Source. See DG_CONTROL / DAT_FILESYSTEM / MSG_CHANGEDIRECTORY and DG_CONTROL / DAT_FILESYSTEM / MSG_GETINFO to get more information about the new device.

TWDE_DEVICEOFFLINE

A device has become unavailable. This is different from TWDC_DEVICEREMOVED, since the device is assumed to be connected.

TWDE_DEVICEREADY

A device is ready to capture another image. Applications should be careful when negotiating this event, especially in situations where images are gathered quickly, as with automatic capture.

TWDE_DEVICEREMOVED

A device has been removed from the Source. This is different from TWDE_DEVICEOFFLINE. As soon as this event is received an Application should re-negotiate its current device, since that may have been the one that was removed. Sources must default to the TWFY_CAMERA device if the current device is removed.

TWDE_PAPERDOUBLEFEED

Report double feeds to the Application. Because of the asynchronous nature of device events there may still be images waiting to be transferred, applications need to decide if they want to recover these images or discard them.

TWDE_PAPERJAM

Report paper jams to the Application. Because of the asynchronous nature of device events there may still be images waiting to be transferred, applications need to decide if they want to recover these images or discard them.

Supported Sizes

Typical uses for ICAP_SUPPORTEDSIZES include, but are not limited to the following: A0, A1 Technical drawings, posters

A2, A3 Drawings, diagrams, large tables

A4 Letters, magazines, forms, catalogs, laser printer and copying machine output

A5 Note pads

A6 Postcards

B5, A5, B6, A6 Books

C4, C5, C6 Envelopes for A4 letters: unfolded (C4), folded once (C5), folded twice (C6)

B4, A3 Newspapers, supported by most copying machines in addition to A4

The following table details the physical dimensions associated with ICAP_SUPPORTEDSIZES. Multiply millimeters by 0.03937 to get the approximate inches. Multiply inches by 25.4 to get the approximate millimeters. ICAP_SUPPORTEDSIZES Description TWSS_NONE Images will match the maximum scanning dimensions of the device. This setting is only applicable to devices that have fixed measurable dimensions, such as most scanners. Devices that do not support physical dimensions should not support ICAP_SUPPORTEDSIZES. TWSS_A LETTER These values are preserved for backward compatibility. TWSS_B LETTER TWAIN 1.8+ enabled Applications should not use these settings. TWSS_B TWSS_B TWSS_B TWSS_B This value is obsolete, and no longer supported by the specification. Do not use it. TWSS_USLETTER 8.5” x 11.0” (216mm x 280mm) TWSS_USLEGAL 8.5” x 14.0” (216mm x 356mm) TWSS_USLEDGER 11.0” x 17.0” (280mm x 432mm) TWSS_USEXECUTIVE 7.25” x 10.5” (184mm x 267mm) TWSS_USSTATEMENT 5.5” x 8.5” (140mm x 216mm) TWSS_BUSINESSCARD 90mm x 55mm TWSS_ A 1682mm x 2378mm TWSS_ A 1189mm x 1682mm TWSS_A 841mm x 1189mm TWSS_A 594mm x 841mm TWSS_A 420mm x 594mm TWSS_A 297mm x 420mm TWSS_A 210mm x 297mm TWSS_A 148mm x 210mm TWSS_A 105mm x 148mm TWSS_A 74mm x 105mm TWSS_A 52mm x 74mm TWSS_A 37mm x 52mm TWSS_A 26mm x 37mm TWSS_ISOB 1000mm x1414mm TWSS_ISOB 707mm x1000mm TWSS_ISOB 500mm x 707mm TWSS_ISOB 353mm x 500mm TWSS_ISOB 250mm x 353mm TWSS_ISOB 176mm x 250mm TWSS_ISOB 125mm x 176mm TWSS_ISOB 88mm x 125mm TWSS_ISOB 62mm x 88mm TWSS_ISOB 44mm x 62mm TWSS_ISOB 31mm x 44mm TWSS_JISB 1030mm x1456mm TWSS_JISB 728mm x1030mm TWSS_JISB 515mm x 728mm TWSS_JISB 364mm x 515mm TWSS_JISB 257mm x 364mm TWSS_JISB 182mm x 257mm TWSS_JISB 128mm x 182mm TWSS_JISB 91mm x 128mm TWSS_JISB 64mm x 91mm TWSS_JISB 45mm x 64mm TWSS_JISB 32mm x 45mm TWSS_C 917mm x1297mm TWSS_C 648mm x 917mm TWSS_C 458mm x 648mm TWSS_C 324mm x 458mm TWSS_C 229mm x 324mm TWSS_C 162mm x 229mm TWSS_C 114mm x 162mm TWSS_C 81mm x 114mm TWSS_C 57mm x 81mm TWSS_C 40mm x 57mm TWSS_C 28mm x 40mm

Automatic Capture

Automatic image capture is intended for Digital Cameras, although there may be opportunities for other kinds of devices. The intention is to allow an Application to control when pictures are taken, how many pictures are taken, and the interval of time between picture taking. All that is required is that the device be able to perform capture on command from the Source, the timing control and storage of pictures may reside in the Source or the device; the Application does not care. There are three capabilities needed to control automatic capture:

CAP_AUTOMATICCAPTURE CAP_TIMEBEFOREFIRSTCAPTURE CAP_TIMEBETWEENCAPTURES

And one triplet: DG_CONTROL/DAT_FILESYSTEM/MSG_AUTOMATICCAPTUREDIRECTORY

CAP_AUTOMATICCAPTURE selects the number of images to be captured. A value of zero (0), the default, disables it. CAP_TIMEBEFOREFIRSTCAPTURE selects how many milliseconds are to pass before the first picture is taken by the device. If this value is 0, then picture taking begins immediately. CAP_TIMEBETWEENCAPTURES selects the milliseconds of elapsed time between pictures. If this value is 0, then the pictures are taken as fast as the device can go. DG_CONTROL / DAT_FILESYSTEM / MSG_AUTOMATICCAPTUREDIRECTORY selects the directory that will receive the images as they are captured. Automatic capture expects the device (or Source) to manage the storage of images until the Application is ready to collect them. Applications may choose to retrieve images as they are captured by the Source (using the DAT_FILESYSTEM triplets to browse the storage directory), but must realize that this may affect the performance of the device. The nature of automatic capture suggests that an Application should be able to disconnect from a Source and expect that if it returns after CAP_TIMEBEFOREFIRSTCAPTURE has passed, there may be images available for it to collect. Because of this Sources should remember their automatic capture settings from session to session, so that a Source starting up does not inadvertently clear them. Applications need to remember that since the capture of images may occur outside of their control that the settings may be changed directly on the device by the user, resulting in alternations in any of the automatic capture settings. Applications that cannot support this uncertainty should clear the Source’s automatic capture settings prior to shutdown (and after notifying the User).

Camera Preview

Some digital cameras offer a way to preview the intended shot through either a continuous flow of low-resolution frames or streaming video. TWAIN exposes two methods for a Source to present this information to an Application, both in association with the TWFY_CAMERAPREVIEW device.

The TWFY_CAMERAPREVIEW Device

Sources that wish to provide access to their preview camera must do so through DAT_FILESYSTEM. A minimum configuration includes a single TWFY_CAMERA and a single TWFY_CAMERAPREVIEW. The Application discovers what devices are available by using the

DAT_FILESYSTEM commands MSG_GETFIRSTFILE and MSG_GETNEXTFILE. It can then switch from the startup default TWFY_CAMERA to the TWFY_CAMERAPREVIEW using the MSG_CHANGEDIRECTORY command.

Performance

It is important when taking a picture from preview mode that the switch from TWFY_CAMERAPREVIEW to TWFY_CAMERA happens as quickly as possible. Applications can minimize the switch over time by negotiating the settings of the TWFY_CAMERA before changing to the TWFY_CAMERAPREVIEW device to collect real-time images. Sources can help by optimizing their communication with the TWFY_CAMERA, perhaps downloading its values when the user sends MSG_ENABLEDS to the TWFY_CAMERAPREVIEW device so that when the switch back occurs all that needs to happen is a command sent to the camera to take a picture. Another matter of importance is the transfer mechanism. If the camera is capable of sending a run of continuous snapshots to the application (as opposed to real video streaming), then it is recommended that the TWFY_CAMERAPREVIEW device only support an ICAP_XFERMECH of TWSX_NATIVE. Entering Preview Mode

An application should do the following before entering preview mode. The application sends MSG_OPENDS to the Source.

The application determines that the Source TWFY_CAMERAPREVIEW device.

The user/application negotiates values for the TWFY_CAMERA device.

The user/application decides to enter preview mode. The application uses MSG_CHANGEDIRECTORY to change to the TWFY_CAMERAPREVIEW device.

The application uses MSG_ENABLEDS to enter preview mode. Note that the value of ShowUI should depend on which of the next two sections the application decides to use to control the Source (GUI mode or programmatic).

Previewing with the Source’s GUI (ShowUI == TRUE)

If the application relies solely on the Source’s GUI for its control of the camera, then it shouldn’t have to worry about preview mode issues, since it is hoped that a Source that supports preview will provide access to it from its GUI. This section is concerned with a more limited area, where an application has opted to control the Source programmatically, except for the use of preview. One reason an application might need to do this is to provide preview support for cameras that output streaming video. TWAIN does not have a mechanism for handling this kind of data, so if the only way that a TWAIN application will be able to show this kind of preview data, is if the Source provides a GUI that can show it. If the Source has CAP_CAMERAPREVIEWUI set to TRUE, then it is possible for the application to use this to preview the images coming from the camera. In this mode the application does not have to concern itself with the kind of data that the Source is providing, since the Source takes the responsibility of displaying the preview images to the user. However, the application does have to wait for the triggers that indicates that the user wishes to take a picture, or that they wish to exit from preview mode. To help standardize this behavior, the preview GUI should be able to indicate two things. Take a picture – if the user selects to take a picture, perhaps by pressing a button labeled CAPTURE, then the Source should send the DAT_NULL command MSG_CLOSEDSOK back to the application.

Cancel preview – if the user decides to exit from preview mode, then the Source should send the DAT_NULL command MSG_CLOSEDSREQ back to the application. The application should then send MSG_DISABLEDS to the Source, change back to the TWFY_CAMERA device, and resume its programmatic control of the Source.

Previewing under Programmatic Control (ShowUI == FALSE):

TWAIN provides programmatic support for TWFY_CAMERAPREVIEW devices that operate by taking a continuous flow of low-resolution snapshots. An application learns that a Source is capable of this by changing to TWFY_CAMERAPREVIEW and testing ICAP_XFERMECH. If the capability is supported, then the TWFY_CAMERAPREVIEW device is capable of transferring these low-resolution images fast enough to simulate real-time video. The way the application obtains these images is similar to how scanners work. The application sets CAP_XFERCOUNT to –1 and enables the Source. The Source sends a MSG_XFERREADY to the application, and the application begins transferring and displaying the low-resolution images as fast as it can. These steps are repeated to aid understanding… The application negotiates any capabilities with the TWFY_CAMERAPREVIEW device, including setting CAP_XFERCOUNT to –1, indicating that the application wishes to receive an unlimited number of images.

The application send MSG_ENABLEDS ShowUI FALSE to the Source.

The Source sends back MSG_XFERREADY and transitions to State 6.

The application uses MSG_IMAGENATIVEXFER to transfer the image and the Source transitions to State 7.

The application displays the image.

The application uses DAT_PENDINGXFERS / MSG_ENDXFER to transition the Source to State 6. The application needs to pay attention to the TW_PENDINGXFERS.Count, but it is expected that it should remain at –1.

Go to step (4).

As long as the application and Source are looping from steps (4) through (7) the application should be displaying a continuous run of snapshots. Since the application is in complete control, it is implementation dependent on how the user indicates that a picture should be taken. However, once the decision to take a picture is made, the steps to do it are as follows… Taking a Picture:

The application should do the following when it is told to take a picture while in preview mode. The application sends DAT_PENDINGXFERS / MSG_ENDXFER to the Source, transitioning from State 7 to State 6 (if necessary).

The application sends DAT_PENDINGXFERS / MSG_RESET to the Source, transitioning from State 6 to State 5.

The application sends MSG_DISABLEDS to the Source, transitioning from State 5 to State 4.

The application uses MSG_CHANGEDIRECTORY to switch from the TWFY_CAMERAPREVIEW device to the TWFY_CAMERA device.

The application uses MSG_ENABLEDS ShowUI FALSE to enable the TWFY|_CAMERA device.

The application sends one of the MSG_IMAGExxxxXFER commands to the Source.

The source takes the full resolution picture and transfers it back to the application

File System

This section consists of the following: Overview

Rules for path and file names

File system components

Rule for root directory

Rules for image directory

File Types

DAT_FILESYSTEM operations

Thumbnails and Sound snippets

Context variable

Condition Codes Note: The term ‘camera’ is used generically in the specification to describe a device that captures an image, and is not limited to just devices that employ a camera to accomplish this.

Overview

Digital cameras and some scanners have the ability to capture images to their own local storage. When Automatic Capturing is being used an Application need not collect the captured images until long after their acquisition. A file system is a good representation for the storage of images (since it is a model that is familiar to most programmers), so TWAIN exposes a simple file system interface that Applications may browse through in a random fashion. There is also a need in TWAIN to expose multiple devices through a single Source. Single pass duplex scanners have multiple cameras that accept different settings. Digital cameras come with disks and memory expansion cards, and many are able to provide a stream of preview images. The file system offers a way for a Source to maintain in its root directory a list of the devices available to an Application.

Rules for Path and File Names

There are two main grouping of files supported by TWAIN; devices, which are associated with real-time capture, which accept image capture settings, and which are of the form:

DeviceName

And image path and file names, which are images on local storage which have been previously captured by the device, and which are of the form (bracketed items are optional):

> DomainName] [ HostName] TopDirectory [ Sub Directory…] ImageFile

A filename consists of any characters except: NUL (0), either of the slashes ‘/’ or ‘\’ and the colon ‘:’.

Sources should at a minimum support the characters: “A-Z a-z 0-9 _ .”

The file system should not be case sensitive, though it may show upper and lowercase.

Applications should take into consideration that internationalized Sources may construct filenames from characters within UNICODE.

The forward slash ‘/’ and backward slash ‘\’ may be used interchangeably in the creation of path names. Sources and Applications must support the use of both slashes. (ex: /abc\xyz).

Multiple adjacent slashes reduce to a single slash. (ex: ///\\abc///xyz == /abc/xyz).

The root directory is designated as a solitary slash (ex: / or \).

The MSG_CHANGEDIRECTORY and MSG_AUTOMATICCAPTUREDIRECTORY operations are the only ones that accepts absolute or relative directory paths. All other operations occur within the current directory.

MSG_CHANGEDIRECTORY and MSG_AUTOMATICCAPTUREDIRECTORY can use dot ‘.’ to address the current directory (ex: ./abc).

MSG_CHANGEDIRECTORY and MSG_AUTOMATICCAPTUREDIRECTORY can use dot-dot ‘..’ to address the parent directory (ex: ../abc).

In the root directory a MSG_CHANGEDIRECTORY or AUTOMATICCAPTUREDIRECTORY to dot- dot ‘..’ is the same as dot ‘.’ (ex: /. == /..).

Examples:

\Camera is the same as Camera Camera is the same as Camera Camera is the same as Camera Camera is the same as Camera

File System Components

A file system consists of the following. A root directory.

A camera device (TWFY_CAMERA), which must be the default device when the Source starts.

Zero or more additional devices (TWFY_CAMERATOP, TWFY_CAMERATOP, TWFY_CAMERAPREVIEW).

It is possible for a Source to support multiples of a given device type, for instance a scanner may support two devices of type TWFY_CAMERA, both with a supporting TWFY_CAMERATOP and TWFY_CAMERABOTTOM. Use pTW_FILESYSTEM >DeviceGroupMask to uniquely identify a camera or to group it with its associated top and bottom cameras. For example: Name Type Group camera_ TWFY_CAMERA x camera_ _top TWFY_CAMERATOP x camera_ _bottom TWFY_CAMERABOTTOM x camera_ TWFY_CAMERA x camera_ _top TWFY_CAMERATOP x camera_ _bottom TWFY_CAMERABOTTOM x

Zero or more directories for storing images (on memory cards, disks, etc…). These are organized in a hierarchical structure that permits, but does not require the ability to browse in a network:

A TWFY_DOMAIN directory contains only TWFY_HOST directories

A TWFY_HOST directory contains only TWFY_DIRECTORY directories

A TWFY_DIRECTORY contains TWFY_IMAGE files and/or TWFY_DIRECTORY directories.

Sources that provide image storage must provide at least one TWFY_DIRECTORY. TWFY_DOMAIN and TWFY_HOST are optional.

Rules for Root Directory

The root directory can only contain devices or directories, not images.

The application cannot create, delete, copy into or rename files in the root directory.

Files in a directory are not ordered in any fashion (for instance, an Application may not assume that they are alphabetically sorted). There is one exception to this rule: when an Application issues a DG_CONTROL / DAT_FILESYSTEM / MSG_GETFIRSTFILE on the root directory, the Source must return a TWFY_CAMERA device. This device is the designated default capture camera. If an Application begins capability negotiation, or image capture without accessing DAT_FILESYSTEM, then this is the device that will be used.

Rules for Image Directory

A TWFY_DIRECTORY can contain 0 or more TWFY_DIRECTORYs (sub-directories).

Can contain 0 or more TWFY_IMAGE (image files).

May be fully accessible, read or write protected.

May be created or deleted by an Application, given that it is not in the root directory, and that it is not protected by the Source.

Context Variable

The reason for the Context variable is that it allows for unconditional mingling of DAT_FILESYSTEM operations. If there was no Context variable, then Applications would be more limited in the order of operations that could be performed. For instance, the recursive directory walk in the code sample would be much harder to accomplish without a Context to help the Source identify the current directory being accessed by a call to MSG_GETNEXTFILE. This value is provided solely for the benefit of Source writers. When MSG_GETFIRSTFILE is called, the Source should record the current directory and the current file and store those values internally, using Context as a reference to their location. The nature or value of the Context is dependent on the implementation of the Source, Applications must never attempt to use or modify the Context. A call to MSG_GETINFO must use this Context to identify the file being reported. Calls to any of the file transfer methods (MSG_IMAGENATIVEXFER, MSG_IMAGEFILEXFER, MSG_IMAGEMEMXFER, MSG_AUDIONATIVEXFER, MSG_AUDIOFILEXFER) must use this Context to determine the data being sent to the Application. A call to MSG_GETNEXTFILE must use this Context to help obtain the next file from the directory (this will result in a change in the context as it references the new file). And, finally, a call to MSG_GETCLOSE releases the memory in the Source associated with this Context.

Condition Codes

These are some condition codes that apply specifically to file system operations: TWCC_DENIED File system operation is denied. A Source should report this condition code if an attempt is made to access a protected file. Examples of such protection include: any attempt to delete, rename or copy into the root directory; protected files that are on the network; and any file that the Source feels it needs to protect.

TWCC_FILEEXISTS The operation failed because the file already exists. A Source should report this condition code if an attempt is made to create a sub-directory with a name that already exists in the targeted directory; or if an attempt is made to copy or rename over an existing file or directory.

TWCC_FILENOTFOUND The file was not found. This can occur for a variety of reasons: attempts to change directory to a path that does not exist; attempts to delete, rename or copy files that do not exist; as the condition code from MSG_GETFIRSTFILE for an empty directory; or MSG_GETNEXTFILE when it finds no more files in the current directory; and, finally, from MSG_GETINFO if it is requested to provide information on a file that has been deleted.

TWCC_NOTEMPTY Operation failed because the directory is not empty. This condition code is used by the Source if an attempt is made with the Recursion flag set to FALSE to delete a non-empty directory.

File Types

The DG_CONTROL / DAT_FILESYSTEM / MSG_CHANGEDIRECTORY operation is used to make either a device or a directory current. If a camera device is the target, then all capability negotiation is with that device and all images come from that device, until a new MSG_CHANGEDIRECTORY command is issued. If an image directory is selected then the current device is set to be the root level directory name (i.e., changing to abc mno xyz means that the current device is abc . TWFY_CAMERA Every TWAIN file system must support at least one camera, which must be the default device on startup. This is for

compatibility with pre 1.8 applications as well as post 1.8 applications that do not choose to make use of the file system. On single pass duplex scanners, this camera device is used to simultaneously set values for the top and bottom cameras. During the capturing of images (in duplex mode) it sends a stream of images in the order: TOP, BOTTOM, TOP…

TWFY_CAMERATOP / TWFY_CAMERABOTTOM

Single pass duplex scanners may opt to provide independent access to the top and bottom cameras. A device with one of these file types controls the settings for the specified camera. If this device is the current device at the time image capture commences, then only images from that camera will be passed to the Application. This means that even if a device is set for duplex scanning, if the current device has a file type of TWFY_CAMERATOP, then only top images will be passed to the Application.

TWFY_CAMERAPREVIEW A logical device that performs camera live preview functionality. When implementing the Source for this logical device, related capabilities must be negotiated to perform preview specific functions. Among them, ICAP_XRESOLUTION and ICAP_YRESOLUTION must be implemented to specify the preview image sizes. Other capabilities may be available in some sources, such as ICAP_ZOOMFACTOR and ICAP_FLASHUSED .

TWFY_DIRECTORY At the root directory level files of this type should correspond to

a physical piece of hardware (a memory card or a disk). The root directory is only allowed to contain devices. Sub-directories may only contain image files or more sub-directories. Access to files and directories is controlled by the Source, so Applications should check all operations and watch out for condition codes such as TWCC_DENIED.

TWFY_IMAGE Any directory, except root, may contain image files. The

DAT_FILESYSTEM messages MSG_GETFIRSTFILE and MSG_GETNEXTFILE select the current image. Once an image has been selected, it may be transferred in the same fashion used to acquire images from a camera. Note: this file type is reserved for full resolution images, see the section on Thumbnails for information on how to acquire them.

DAT_FILESYSTEM Operations

MSG_AUTOMATICCAPTUREDIRECTORY

Selects the directory to be used to store images acquired by automatic capture.

MSG_CHANGEDIRECTORY

Selects the device or image subdirectory. Use this to select between direct camera (scanner) control, and browsing of stored images. All capabilities negotiated and triplet operations are with the current device (directory), until this value is changed by the Application.

MSG_COPY Copies the specified file from one directory to another. If the

Recursive flag is TRUE and the file type specified is TWFY_DIRECTORY then that directory and all the files and directories under it are copied. The Application cannot copy files into the root directory.

MSG_CREATEDIRECTORY Creates a new image subdirectory. The Application cannot create files in the root directory.

MSG_DELETE Deletes the specified file. If the Recursive flag is TRUE and the

file type specified is TWFY_DIRECTORY, then all the files under that directory are deleted. The Application cannot delete files in the root directory.

MSG_FORMATMEDIA Formats the currently selected storage device. Use with caution.

MSG_GETCLOSE Closes the Context created by MSG_GETFIRSTFILE.

MSG_GETFIRSTFILE Creates a Context that points to the first file in a directory. This

Context is used by MSG_GETINFO, MSG_GETNEXTFILE, MSG_GETCLOSE; and for files of type TWFY_IMAGE all image transfer related operations performed in states 6 and 7 use the image pointed to by this Context (i.e., DAT_IMAGEINFO, DAT_IMAGEMEMXFER, etc…).

MSG_GETINFO Returns information about a device, directory or image file.

MSG_GETNEXTFILE Updates the Context to point to the next file in the directory.

MSG_RENAME Renames a directory or an image file. If the directories differ,

then it moves the file as well, creating it in the new location and deleting it from the old location. Files in the root directory cannot be renamed by the Application.

Thumbnails and Sound Snippets

TWAIN is primary concerned with the acquisition of images, so the file system does not contain thumbnail files or sound files, since these kinds of data are expected to be associated with image files. This simplifies an Application’s browsing of the file system, since it need only concern itself with one type of data file (TWFY_IMAGE), and does not have to trace associated data files. Sources must filter out non-image files, if the device stores thumbnail and sound data independent of the image files. For instance, if a device stores the following files:

IMAGE TIF

IMAGE _THUMBNAIL TIF IMAGE _SOUND WAV

The file system must only report the existence of IMAGE TIF An Application obtains the thumbnail for an image by setting ICAP_THUMBNAILSENABLED to TRUE; the same filename is used for both the full resolution and thumbnail versions of an image. By setting ICAP_THUMBNAILSENABLED, the Application decides which version of the image it receives. Sound snippets are also associated with image files, unlike thumbnails it is possible for a single image file to own several sound snippets. An Application can get the number of snippets that an image owns, and then, during image transfer, the Application has the option to transfer any number of those snippets. It is also possible to collect the snippets for an image without transferring the image data.

Sample Recursive Directory Walk

The following is a sample recursive directory walk. This Application function walks through all the files in a Source’s file system counting the file types file system counting the file

types it finds It is intended only as a sample error checking is omitted to simplify the code

typedef struct { int Devices int Directories int Images

} t_Counters

TW_UINT DirectoryWalk TW_FILESYSTEM fsArg t_Counters Counters

{

TW_UINT rc TW_FILESYSTEM fs

Caller has set fsArg >InputFile to some value such as “ ”… rc DS_Entry app src DG_CONTROL DAT_FILESYSTEM MSG_CHANGEDIRECTORY fsArg

We do GETFIRSTFILE first in each new directory GETNEXTFILE for all subsequent calls… for rc DS_Entry app src DG_CONTROL DAT_FILESYSTEM MSG_GETFIRSTFILE fs rc TWRC_SUCCESS

rc DS_Entry app src DG_CONTROL DAT_FILESYSTEM MSG_GETNEXTFILE fs { Count the appropriate file type… switch fs FileType { default Counters >Devices break

case TWFY_IMAGE Counters >Images break case TWFY_DOMAIN case TWFY_HOST

case TWFY_DIRECTORY

Counters >Directories

Recursively step into this directory looking for more stuff… rc DirectoryWalk fs Counters if rc TWRC_SUCCESS { rc DS_Entry app src DG_CONTROL DAT_FILESYSTEM

MSG_GETCLOSE fs

return rc

}

break

}

}

Cleanup and return…

rc DS_Entry app src DG_CONTROL DAT_FILESYSTEM MSG_GETCLOSE fs return TWRC_SUCCESS }

Using this function… TW_UINT rc TW_FILESYTEM fs t_Counters Counters memset fs sizeof fs memset Counters sizeof Counters

strcpy fs InputFile ” ” start at root… rc DirectoryWalk fs Counters

Internationalization

A TWAIN Source can easily be internationalized despite its 8-bit character interface. A well designed Source should automatically match the locale of the application calling it; passing localized data through the API, and displaying appropriate language text in its user interface. Developers have the option of using UNICODE or MultiByte encodings, the 8-bit interface is not an obstacle to Applications or Sources.

When an Application calls DG_CONTROL / DAT_IDENTITY / MSG_OPENDS, it provides to the Source its TW_IDENTITY data. Internationalized Sources should check the appIdentity- >Version.Language field, and attempt to match the Application’s language (returning the same value in the dsIdentity structure). If the Source is incapable of matching the language, then it should attempt to match the User’s current locale (on Win32 do this using the LOCALE_USER_DEFAULT value returned by the GetLocaleInfo call). In most cases the Application locale and the User locale will be the same, and the Source will have to select the best language it can. For instance, if the Application requested Swiss French, and the Source only has French, then it should offer that. Otherwise, it should resort to some common secondary language, such as English.

Please note that DG_CONTROL / DAT_IDENTITY / MSG_OPENDS is the very first opportunity that an Application and Source have to negotiate language. DG_CONTROL / DAT_IDENTITY / MSG_GET, when invoked in state 3, does not provide an appIdentity. Sources should default to the LOCALE_USER_DEFAULT in this instance.

As mentioned above, the TWAIN interface assumes 8-bit characters, this prevents the direct passing of UNICODE data between Sources and Applications, but it does not hinder indirect means that convert data into MultiByte encodings. The remainder of this section shows one way of allowing Sources and Applications to communicate, without worrying about whether they are UNICODE or MultiByte enabled. The best example to illustrate this is to consider a Source and Application, both UNICODE enabled, communicating through the TWAIN interface.

To pass UNICODE string data from the Source to the Application, the Source must convert UNICODE to MultiByte, using the appropriate Code-Page (which is specific to a given set of locales). When the Application receives the data, it converts from MultiByte back to UNICODE. The process is the same when sending string data from the Application to the Source. The process depends on the Application and Source using the same Code-Page for their conversion. The Win32 functions required to perform the conversions are WideCharToMultiByte and MultiByteToWideChar. The only limitation to watch out for is the size of the various strings provided by TWAIN. At all times the MultiByte data must fit within the strings described by the interface, and Source and Application writers need to pay close attention to it.

int WideCharToMultiByte(

UINT CodePage, // code page

DWORD dwFlags, // performance and mapping flags LPCWSTR lpWideCharStr, // address of wide-character string int cchWideChar, // number of characters in string LPSTR lpMultiByteStr, // address of buffer for new string int cchMultiByte, // size of buffer LPCSTR lpDefaultChar, // address of default for unmappable characters LPBOOL lpUsedDefaultChar // address of flag set when default char. used );

int MultiByteToWideChar(

UINT CodePage, // code page

DWORD dwFlags, // character-type options LPCSTR lpMultiByteStr, // address of string to map int cchMultiByte, // number of characters in string LPWSTR lpWideCharStr, // address of wide-character buffer int cchWideChar // size of buffer );

These functions are fully described in the online Microsoft Visual C++ documentation. This section does not attempt to duplicate that information, but does show how Source and Application may cooperate when using them to transmit localized data through the TWAIN interface.

TWAIN CAP_LANGUAGE Code to ANSI Code-Page Table

This array maps TWAIN CAP_LANGUAGE codes to the appropriate ANSI Code Page There is no mechanism for converting to the OEM Code Page nor should one be needed since the upper bytes in the OEM pages mostly contain line art characters used by MS DOS Note the index in the comment field is just an index into the array it does not correspond to the TWAIN constant for a given TWLG field…

define AnsiCodePageElements int AnsiCodePage[AnsiCodePageElements] { TWLG_DANISH TWLG_DAN TWLG_DUTCH TWLG_DUT

TWLG_ENGLISH TWLG_ENG TWLG_FRENCH_CANADIAN TWLG_FCF TWLG_FINNISH TWLG_FIN TWLG_FRENCH TWLG_FRN

TWLG_GERMAN TWLG_GER

TWLG_ICELANDIC TWLG_ICE

TWLG_ITALIAN TWLG_ITN

TWLG_NORWEGIAN TWLG_NOR

TWLG_PORTUGUESE TWLG_POR

TWLG_SPANISH TWLG_SPA

TWLG_SWEDISH TWLG_SWE

TWLG_ENGLISH_USA TWLG_USA TWLG_AFRIKAANS TWLG_ALBANIA TWLG_ARABIC TWLG_ARABIC_ALGERIA TWLG_ARABIC_BAHRAIN TWLG_ARABIC_EGYPT TWLG_ARABIC_IRAQ TWLG_ARABIC_JORDAN TWLG_ARABIC_KUWAIT TWLG_ARABIC_LEBANON TWLG_ARABIC_LIBYA TWLG_ARABIC_MOROCCO TWLG_ARABIC_OMAN TWLG_ARABIC_QATAR TWLG_ARABIC_SAUDIARABIA TWLG_ARABIC_SYRIA TWLG_ARABIC_TUNISIA TWLG_ARABIC_UAE United Arabic Emirates TWLG_ARABIC_YEMEN TWLG_BASQUE TWLG_BYELORUSSIAN TWLG_BULGARIAN TWLG_CATALAN TWLG_CHINESE TWLG_CHINESE_HONGKONG TWLG_CHINESE_PRC People s Republic of China TWLG_CHINESE_SINGAPORE TWLG_CHINESE_SIMPLIFIED TWLG_CHINESE_TAIWAN TWLG_CHINESE_TRADITIONAL TWLG_CROATIA TWLG_CZECH TWLG_DUTCH_BELGIAN TWLG_ENGLISH_AUSTRALIAN TWLG_ENGLISH_CANADIAN TWLG_ENGLISH_IRELAND TWLG_ENGLISH_NEWZEALAND

TWLG_ENGLISH_SOUTHAFRICA TWLG_ENGLISH_UK TWLG_ESTONIAN TWLG_FAEROESE TWLG_FARSI TWLG_FRENCH_BELGIAN TWLG_FRENCH_LUXEMBOURG TWLG_FRENCH_SWISS TWLG_GERMAN_AUSTRIAN TWLG_GERMAN_LUXEMBOURG TWLG_GERMAN_LIECHTENSTEIN TWLG_GERMAN_SWISS TWLG_GREEK TWLG_HEBREW TWLG_HUNGARIAN TWLG_INDONESIAN TWLG_ITALIAN_SWISS TWLG_JAPANESE TWLG_KOREAN TWLG_KOREAN_JOHAB TWLG_LATVIAN TWLG_LITHUANIAN TWLG_NORWEGIAN_BOKMAL TWLG_NORWEGIAN_NYNORSK TWLG_POLISH TWLG_PORTUGUESE_BRAZIL TWLG_ROMANIAN TWLG_RUSSIAN TWLG_SERBIAN_LATIN TWLG_SLOVAK TWLG_SLOVENIAN TWLG_SPANISH_MEXICAN TWLG_SPANISH_MODERN TWLG_THAI TWLG_TURKISH TWLG_UKRANIAN }

Sample Converting from WideChar to MultiByte

The following is a sample of converting from WideChar to MultiByte.

This function converts _TCHAR strings to MultiByte using the appropriate code page If the build is ANSI or MBCS then no conversion is needed the _tcsncpy function is used If the build is UNICODE then the Code Page is determined and used to convert the string to MultiByte using the WideCharToMultiByte function…

int CopyTCharToMultibyte char dst const int sizeof_dst const _TCHAR src const int twain_language_code

{

ifndef _UNICODE

MultiByte string copy…

_tcsncpy dst src sizeof_dst dst[sizeof_dst ] return strlen dst

else

int cp int len _TCHAR cp_str[ ]

if twain_language_code > AnsiCodePageElements {

Whoops don’t have one of those… return } else if twain_language_code > {

Lookup the code page…

cp AnsiCodePage[twain_language_code]

} else {

Get the User’s code page… GetLocaleInfo LOCALE_USER_DEFAULT LOCALE_IDEFAULTANSICODEPAGE cp_str sizeof cp_str cp _ttoi cp_str

}

if IsValidCodePage cp {

That code page isn’t installed on this system… return }

len WideCharToMultiByte cp code page performance and mapping flags

src address of wide character string number of characters in string dst address of buffer for new string sizeof_dst size of buffer in characters NULL address of default for unmappable characters

NULL address of flag set when default char used endif

}

Sample Converting from MultiByte to WideChar

The following is a sample of converting from MuliByte to WideChar.

This function converts multibyte strings to _TCHAR strings using the appropriate code page If the build is ANSI or MBCS then no conversion is needed the

_tcsncpy function is used If the build is UNICODE then the Code Page is determined and used to convert the string to _TCHAR using the MultiByteToWideChar function…

int CopyMultibyteToTChar

_TCHAR dst

const int sizeof_dst const char src const int twain_language_code

{

ifndef _UNICODE

MultiByte string copy…

_tcsncpy dst src sizeof_dst dst[sizeof_dst ] return strlen dst else int cp int len _TCHAR cp_str[ ]

if twain_language_code > AnsiCodePageElements {

Whoops don’t have one of those… return } else if twain_language_code > {

Lookup the code page…

cp AnsiCodePage[twain_language_code]

} else {

Get the User’s code page… GetLocaleInfo

LOCALE_USER_DEFAULT LOCALE_IDEFAULTANSICODEPAGE cp_str sizeof cp_str cp _ttoi cp_str

}

if IsValidCodePage cp {

That code page isn’t installed on this system… return }

len MultiByteToWideChar

cp code page

performance and mapping flags

src address of wide character string number of characters in string dst address of buffer for new string sizeof_dst sizeof _TCHAR size of buffer in characters return len endif }

Sample Use of the Conversion Functions

The following are examples of UNICODE application and UNICODE source. UNICODE Application int sts

int twain_language_code

_TCHAR Author[ ] pTW_ONEVALUE pvalOneValue the Application has queried the Source as to what languages it supports and selected TWLG_JAPANESE storing it in twain_language_code… CAP_AUTHOR is queried and a value is received… Convert CAP_AUTHOR string to UNICODE… sts CopyMultiByteToTChar Author sizeof Author char pvalOneValue >Item twain_language_code if sts { Error… }

UNICODE Source int sts

int source_language_code

_TCHAR SourceAuthor[ ] pTW_ONEVALUE pvalOneValue the Source has been told to use TWLG_JAPANESE it stores this value in source_language_code … CAP_AUTHOR is queried by the Application… The Source keeps the value in SourceAuthor… Convert CAP_AUTHOR string to multibyte… sts CopyTCharToMultibyte char pvalOneValue >Item sizeof TW_STR SourceAuthor source_language_code if sts { Error… } The Source returns the value to the Application…

Audio Snippets

Digital Cameras have the ability to acquire audio snippets along with an image. To support this TWAIN 1.8 provides a new data group, DG_AUDIO. Because TWAIN is image-centric, DG_AUDIO operations are dependent on an image context, audio snippets must be associated with an image. When a Source enters into state 6, the Application can opt to transfer any and all audio snippets. The steps required to obtain audio snippets deliberately parallel the steps required to transfer images, to reduce the effort to learn how to access this new kind of data. The following Data Argument Types (DATs) are supported by DG_AUDIO: DAT_AUDIOFILEXFER transfer audio in file format

DAT_AUDIOINFO info about an audio snippet

DAT_AUDIONATIVEXFER transfer audio in native format

The following DG_CONTROL (DATs) are supported when DAT_XFERGROUP is set to DG_AUDIO, DATs not mentioned in this list must return TWRC_FAILURE / TWCC_BADPROTOCOL: DAT_CAPABILITY no changes to its operation

DAT_EVENT no changes to its operation

DAT_IDENTITY no changes to its operation

DAT_NULL no changes to its operation

DAT_PASSTHRU no changes to its operation

DAT_PENDINGXFERS reports number of snippets remaining to be transferred, MSG_ENDXFER and MSG_RESET do not cause the Source to drop to State 5.

DAT_SETUPFILEXFER selects the audio file format

DAT_STATUS no changes to its operation

DAT_USERINTERFACE no changes to its operation

DAT_XFERGROUP MSG_SET, MSG_GETDEFAULT and MSG_GETCURRENT added to allow switching between data groups. The default value for MSG_GETDEFAULT must be DG_IMAGE. And when the Source starts up, MSG_GETCURRENT must report DG_IMAGE as the current data group, to maintain compatibility with pre-TWAIN 1.8 Applications.

The following capabilities support audio; all capabilities are negotiable at all times (at least in state 4), independent of the current setting of DAT_XFERGROUP: ACAP_XFERMECH negotiate audio snippet transfer mechanism

Collecting Audio Snippets

The transfer of an audio snippet was designed to be used when an Application is browsing through a selection of stored images. There is nothing to prevent the transfer of audio when an image is captured in real-time, though TWAIN does require that any audio snippets be transferred before the image is transferred. A typical transfer may occur in the following way: An Application is browsing through storage managed by the TWAIN Source using MSG_GETFILEFIRST / MSG_GETFILENEXT (see DAT_FILESYSTEM), and finds an image that it wants to work with. The Application enters state 6 by calling DG_CONTROL / DAT_IDENTITY / MSG_ENABLEDS. If the Application wants to find out if there are any audio snippets associated with the image, it can call DG_AUDIO / DAT_AUDIOINFO / MSG_GET. In this example it finds in the TW_AUDIOINFO structure that this image file has three audio snippets associated with it. The Application wants the second audio snippet, so it calls DG_CONTROL / DAT_XFERGROUP / MSG_SET and sets the data group to DG_AUDIO. This call changes the context of the Source, it is now set up to transfer audio data. One effect of this is that a call to DG__CONTROL / DAT_PENDINGXFERS / MSG_GET will report the number of audio snippets (for this image) that remain to be transferred. Because the Application wants the second audio snippet, it must discard the first one, and does this by making a call to DG_CONTROL / DAT_PENDINGXFERS / MSG_ENDXFER. The snippet that it wants is now available to be transferred, and it does this with a call to DG_AUDIO / DAT_AUDIONATIVEXFER / MSG_GET. The Source moves up into state 7. The Application ends the transfer with a call to DG_CONTROL / DAT_PENDINGXFERS / MSG_ENDXFER. Because the Application only wanted the second audio snippet, it can return to DG_IMAGE by making a call to DG_CONTROL / DAT_XFERGROUP / MSG_SET. Once this is done, all other commands work in a traditional TWAIN fashion. The Application can opt to transfer or discard the image, even though it did not transfer all of the audio snippets. There is one more thing to note, if the Application had read the third audio snippet, or if it had issued the DG_CONTROL / DAT_PENDINGXFERS / MSG_RESET command while in DG_AUDIO, the state of the Source would remain at state 6. TWAIN works this way because it is image-centric, the only way to transition from state 6 to state 5 is when it is determined that there are no more images to transfer.

Notes

TWAIN 1.8 supports native and file transfers of audio snippets. Buffered mode transfers are not supported, because TWAIN does not have the necessary infrastructure to describe audio data, and it was decided that adding that structure in this release would be overly complex, and probably incomplete.

As a general rule, even though many operations are possible with DAT_XFERGROUP set to DG_AUDIO, Applications are encouraged to only change to DG_AUDIO for the length of time it takes to collect an audio snippet, and to stay in DG_IMAGE mode at all other times.

Though TWAIN is image-centric, it is possible to envision a TWAIN Source that is only capable of supporting DG_AUDIO. The TWAIN Working Group feels that any such notion is a bad idea, and encourages anyone thinking of doing this to pick on some other API.

How to use the Preview Device

Application Switch to the Preview Logical Device

The application first tries to switch to the preview logical device using the DG_CONTROL / DAT_FILESYSTEM / MSG_CHANGEDIRECTORY triplet with TWFY_CAMERAPREVIEW set in InputName field of TW_FILENAME structure. If the returned value is TW_SUCCESS, the application can proceed. After the application successfully switches to the preview device, all subsequent capability negotiation is with the preview device.

The application queries the Source with capability CAP_CAMERAPREVIEWUI. If it returns SUCCESS, then the Source is able to assume the responsibility of displaying preview images. The application can choose to use the Source’s UI or not when it issues the MSG_ENABLEDS. If the application uses the Source’s UI, it will do nothing but wait to issue MSG_DISABLEDS, or wait for a MSG_CLOSEDSREQ from the Source to stop the preview mode. If the application does not use the Source’s UI or the Source does not provide a UI, then the application should follow the following steps.

Setting Up Environments for Preview Mode

The application starts negotiation on the Preview size using the ICAP_XRESOLUTION and ICAP_YRESOLUTION capabilities with MSG_GET first. With the returned supported sizes from

the Source, the application can set the selected preview sizes using the ICAP_XRESOLUTION and ICAP_YRESOLUTION capabilities with MSG_SET.

Optionally, the application can negotiate the zoom lens value, camera flash state during previewing, etc, with available capabilities such as ICAP_ZOOMFACTOR, ICAP_FLASHUSED . If application queries for capabilities that are not related to preview device, Source will return TWRC_FAILURE.

Start Getting and Displaying Preview Thumbnails

The application can use the automatic capture feature with CAP_XFERCOUNT to -1 (Application is willing to transfer multiple images).

Application issues MSG_ENABLEDS to move to state 5. Upon receiving this message, the Source should start capturing images1.

Source issues MSG_XFERREADY, indicating that an image is present, and state moves to 6. LOOP:

Application issues DAT_IMAGENATIVEXFER to get image and goes to state 7.

Application issues MSG_ENDXFER to return to state 6, and it displays the image. Then if it wants the next preview image, examines pTW_PENDINGXFERS >Count to verify that there is another image, and it goes to LOOP. Source, upon receiving the MSG_ENDXFER message, takes the next picture and returns -1 in the pTW_PENDINGXFERS >Count.

END LOOP If the application wants to end preview mode, it issues DAT_PENDINGXFERS / MSG_RESET. This forces the Source to go to state 5 (CAP_XFERCOUNT is set to 0). If the Source is unable to deliver preview images, it sets pTW_PENDINGXFERS >Count to 0 in reply to the application’s MSG_ENDXFER command, and returns to state 5.

The application can then issue MSG_DISABLEDS, which returns it to state 4, and now the application can use DG_CONTROL / DAT_FILESYSTEM / MSG_CHANGEDIRECTORY to change directory to the camera device to take a full resolution picture.

How to Take a Snapshot from Preview Scene

The application could provide a button or menu item for the user to take a snapshot from the preview scene, for example, a “Take Picture” button. In response to this, the application should use the triplet DG_CONTROL / DAT_FILESYSTEM / MSG_CHANGEDIRECTORY with TWFS_CAMERA set in the TW_FILENAME structure to stop the preview mode.

Subsequently, the application can use the automatic capture feature with CAP_XFERCOUNT to 1, CAP_TIMEBEFOREFIRSTCAPTURE to 0 and CAP_AUTOMATICCAPTURE set to 1 to initiate the capture of preview snapshot.

When the Source receives the CAP_AUTOMATICCAPTURE, it should capture the preview snapshot, and inform the application with MSG_XFERREADY when it is ready to transfer.

After receiving the MSG_XFERREADY, the application should use one of the three standard image transfer methods to transfer the captured image from the Source to the application.

The Source takes a picture as soon as it receives MSG_ENABLEDS and each time it receives MSG_ENDXFER

5. At the end of this operation, the application has the option of going back to the preview thumbnail loop.

Imprinter / Endorser

Scanners intended for document imaging sometimes include accessories that let the scanner print data on the documents as it scans them. TWAIN provides basic functionality to negotiate capabilities for imprinter / endorser devices. An imprinter is a general term for any document- printing device. An endorser is more specialized, and is primarily intended as proof of scanning. In addition to the type of printing device, TWAIN offers ways to locate the printer on the scanning path: top or bottom of the sheet of paper, before or after the paper has been scanned. It is the responsibility of the Source to provide the available combinations to the Application. It is the responsibility of the Application to enable the printers that it wants to use, and to establish seed values prior to scanning. This is a context sensitive scheme, Applications use CAP_PRINTER to discover what printers are available to the Source, and to select each of those printers for negotiation. CAP_PRINTERENABLED determines whether or not a given printer will be used when scanning begins; a value of TRUE indicates that it will be used, a value of FALSE that it will not be used. Applications must enable a printer before negotiating the seed values. CAP_PRINTERINDEX describes an index that counts by ones for every image seen by a given printer. CAP_PRINTERMODE selects one of four options: print one line of text from CAP_PRINTERSTRING, or multiple lines from CAP_PRINTERSTRING, a compound string constructed (in order) from CAP_PRINTERSTRING, CAP_PRINTERINDEX and CAP_PRINTERSUFFIX, or an image address string from CAP_PRINTERSTRING, TWEI_IAFIELD _VALUE, and CAP_PRINTERSUFFIX. CAP_PRINTERSTRING specifies the base message to be printed. For compound strings, the CAP_PRINTERSTRING serves as the prefix to the CAP_PRINTERINDEX or TWEI_IAFIELD _VALUE. CAP_PRINTERSUFFIX is only available for compound strings and describes the text (if any) that is to follow the CAP_PRINTERINDEX or TWEI_IAFIELD _VALUE. CAP_PRINTERVERTICALOFFSET specifies Y-Offset for current CAP_PRINTER device.

Example of Use:

Consider a Source that supports two CAP_PRINTERs:

TWPR_IMPRINTERTOPBEFORE TWPR_IMPRINTERBOTTOMBEFORE

The Application then: uses CAP_PRINTER to discover the two printers

sets CAP_PRINTER to TWPR_IMPRINTERTOPBEFORE

sets CAP_PRINTERENABLED to TRUE (turning this printer on)

sets CAP_PRINTERMODE to TWPM_SINGLESTRING

sets CAP_PRINTERSTRING to a string containing today’s date

sets CAP_PRINTER to TWPR_IMPRINTERBOTTOMBEFORE

sets CAP_PRINTERENABLED to FALSE (turning this printer off)

Note that the value of CAP_PRINTER is not important at the time of scanning, it is the other capabilities that control the imprinter, like CAP_PRINTERENABLED; CAP_PRINTER only selects the current printer under negotiation.

Capability Ordering

As the number of capabilities described by TWAIN has increased it has become clear that there are dependencies between many of them. The purpose of this section is to point out connections between certain capabilities. The way one capability can affect another is not always obvious and failure to recognize this interdependence is often the reason for unexpected TWAIN Scanning results. Using this as a guideline, an Application Developer can code capability negotiation with confidence, and Data Source developers can refer back to this section to make sure they have not introduced an unusual dependency. In some cases these dependencies are not likely to be critical, for example if ICAP_CCITTKFACTOR is set to some non-zero value, and ICAP_COMPRESSION is not TWCP_GROUP D, most scanners will not see this as a problem. On the other hand, if ICAP_COMPRESSION is set to TWCP_JPEG and ICAP_XFERMECH is set to TWSX_NATIVE then it is extremely unlikely that the Application will get useable image data. It is the responsibility of the Source to properly constrain itself according to the current settings of all of its capabilities. Doing so has the following benefits: The Source protects itself from illegal configurations.

The Source reports to the Application through constraints and the TWCC_CAPSEQERROR condition code which capabilities are fully, partially or currently not negotiable.

It is the responsibility of the Application to negotiate capabilities in the proper order. Doing so has the following benefits: The Application protects itself from illegal configurations.

The Application can use constraints and occurrences of TWCC_CAPSEQERROR to modify the behavior of its user interface, better representing the Source’s capabilities to the user.

The reset of this article is written in the order of negotiation that an Application should use to control a Source. One other note about interpreting this section, the entire list of capabilities is in the context of the Current File System Device. If the Current File System Device was changed using the DAT_FILESYSTEM triplets, the context of these capabilities is expected to change and re- negotiation must occur. It is much easier to deal with if the File System operations are completed first and Capability negotiation on a large scale is left until just before scanning from a particular device.

Language Support

The first thing the Source and Application should negotiate is the language. This negotiation best occurs as part of the DG_CONTROL / DAT_PARENT / MSG_OPENDS call. The Application reports the language it is using in appIdentity >Version Language. The Source should attempt to try to match this language. If it cannot, it should attempt to match the language that the user logged in with. If this fails then is should pick the best language that it can. For those Sources that support CAP_LANGUAGE the Application has a further opportunity to try and get a good language match, and this should be done as soon as the Source is successfully opened.

Duplex Control

If an Application finds that CAP_DUPLEX exists and it indicates that duplex scanning is supported, then the Application should negotiate CAP_DUPLEXENABLED. If CAP_DUPLEXENABLED is set to FALSE, then DAT_FILESYSTEM capable Sources should not report any TWFY_CAMERABOTTOM devices in the root directory. If the Source is set to a TWFY_CAMERABOTTOM device at the time that CAP_DUPLEXENABLED is set to FALSE, then it should automatically change itself to the corresponding TWFY_CAMERATOP device.

Device Negotiation

If the Source supports DAT_FILESYSTEM, then the Application needs to walk through the root directory to determine what devices are available, if it wants to independently control the individual devices. Sources are required to default to the TWFY_CAMERA device (the implied default for Sources that do not support DAT_FILESYSTEM). If an Application negotiates capabilities using this device, then the Source is expected to apply the settings to as many of its applicable devices as possible. For instance, in a duplex scanner changing the value of ICAP_BRIGHTNESS for the default TWFY_CAMERA device will change the settings of its corresponding TWFY_CAMERATOP and TWFY_CAMERABOTTOM. Once the list of devices has been identified, the Application may optionally change to one of them using DG_CONTROL / DAT_FILESYSTEM / MSG_CHANGEDIRCTORY.

Supported Capabilities

Applications are encouraged to use this call to get the capabilities supported by a Source, since this information can be used to quickly characterize the device. For instance, a Source that supports ICAP_FLASH is more likely to be a digital camera than a scanner. Or in another case, a single-pass duplex scanner that supports DAT_FILESYSTEM access to both of its cameras might not support all the same capabilities for both cameras.

Extended Capabilities

Beginning with TWAIN 2.3 the Data Source always sets CAP_EXTENDEDCAPS to the array of capabilities that are negotiable in States 5, 6 and 7. The application reads this array, or (for legacy purposes) it can set the array to the desired values, and, if TWRC_CHECKSTATUS is returned, follow up to see which values were accepted.

Feeder Control

CAP_FEEDERENABLED is the key capability to determine if a Source supports an automatic document feeder (ADF). Once this value has been determined no special ordering is required to test most of the other values, although there are groupings worth noting. Some ADFs provide control over individual sheets of paper: CAP_CLEARPAGE, CAP_FEEDPAGE, CAP_REWINDPAGE. Some ADFs are supported by memory buffers built into the device: CAP_AUTOSCAN, CAP_MAXBATCHBUFFERS. Some ADFs are capable of detecting the presence of paper in the input bin: CAP_PAPERDETECTABLE, CAP_FEEDERLOADED. ICAP_FEEDERTYPE reports either the types of feeders available (in the case where there is a general type feeder only) or the scan types supported through the feeder. Some ADFs provide control over paper handling: CAP_PAPERHANDLING.

Frame Management

Before negotiating frame information an Application should first establish the unit of measurement using ICAP_UNITS. It should establish the ICAP_XRESOLUTION and ICAP_YRESOLUTION of the image, especially if TWUN_PIXEL is supported, since the reported values should vary with the pixel density. After that the Application should determine the physical limits of the Source using ICAP_MINIMUMHEIGHT, ICAP_MINIMUMWIDTH, ICAP_PHYSICALHEIGHT and ICAP_PHYSICALWIDTH. Note: ICAP_MINIMUMHEIGHT, ICAP_MINIMUMWIDTH, ICAP_PHYSICALHEIGHT, and ICAP_PHYSICALWIDTH may vary depending on the source of the document. For example, when using a Flatbed / ADF combination scanner, the ADF path may permit longer documents to be scanned. In this case, values for these extents would be expected to differ for different values of CAP_FEEDERENABLED. DAT_IMAGELAYOUT is required by all Sources. Most scanners support ICAP_SUPPORTEDSIZES (unlike digital cameras, which tend to not support physical measurements like inches and centimeters). ICAP_SUPPORTEDSIZES is required to set itself to TWSS_NONE if frames are negotiated using either DAT_IMAGELAYOUT or ICAP_FRAMES. ICAP_MAXFRAMES will report how many frames ICAP_FRAMES is capable of delivering per captured item. ICAP_ORIENTATION is intended to tell a Source how the orientation of a sheet of paper fed into the scanner varies from the settings of its frame information. ICAP_ROTATION is a specific request to the scanner to rotate the scanned image the indicated number of degrees. ICAP_ORIENTATION with ICAP_SUPPORTEDSIZES will affect ICAP_FRAMES and DAT_IMAGELAYOUT. ICAP_ROTATION should only affect the output from DAT_IMAGEINFO. The reason for negotiating these values after establishing the frame is that some Sources may reject attempts to rotate data if one of the dimensions exceeds the physical width or height of the scanner. ICAP_OVERSCAN is intended as a way to capture image data beyond the usual boundaries of a scanned sheet of paper, and is primarily intended as an aid in deskewing images. The additional scan area is only reported with DAT_IMAGEINFO. The reason for negotiating this value after setting the other values listed above is that some Sources may reject overscan if certain dimensions are exceeded. ICAP_AUTOMATICDESKEW will correct the rotation of an image, it may also affect the dimensions of the image as reported by DAT_IMAGEINFO. ICAP_AUTOMATICBORDERDETECTION reduces or removes the border generated around an image by the scanner scanning its own platen (the area not covered by the paper). ICAP_UNDEFINEDIMAGESIZE may be set to TRUE by a Source depending on one or more of the previously negotiated capabilities. Applications need to remember that it is possible for images to exceed the width and height dimensions, which can impact the amount of allocated memory. It is also important to note that if the width is undefined and ICAP_XFERMECH is set to TWSX_MEMORY, then the Source is required to also set ICAP_TILES to TRUE.

Bar Code Negotiation

ICAP_BARCODEDETECTIONENABLED must be set before any of the other, related capabilities are made available. ICAP_SUPPORTEDBARCODETYPES should then be tested, to determine what bar- code values are supported by the Source. After that the bar-code capabilities may be negotiated in any order.

Patch Code Negotiation

ICAP_PATCHCODEDETECTIONENABLED must be set before any of the other, related capabilities are made available. ICAP_SUPPORTEDPATCHCODETYPES should then be tested, to determine what patch-code values are supported by the Source. After that the patch-code capabilities may be negotiated in any order. Image Address Negotiation

CAP_IMAGEADDRESSENABLED must be set before any of the other, related capabilities are made available. CAP_SUPPORTEDCAPS will already have reported which CAP_IAFIELD _ capabilities are supported by the Source. Negotiation must be in the order of: CAP_IMAGEADDRESSENABLED, CAP_IAFIELD _LEVEL, CAP_IAFIELD _PRINTFORMAT, CAP_IAFIELD _VALUE. CAP_IAFIELD _LASTPAGE only contains a valid value when a scan session is complete (in state 4 or state 5).

Imprinter/Endorser Negotiation

CAP_PRINTER establishes what (if any) printer/endorsers are supported by the Source. Selecting one establishes a context for that printer/endorser that is used by all related capabilities. CAP_PRINTERENABLED turns the printer on or off; the printer must be on in order for the other settings to be negotiated. A Source may opt to refuse to enable a printer if ICAP_SUPPORTEDSIZES selects a document with a size that is not within the area of the printer. CAP_PRINTERINDEX should be negotiated next. CAP_PRINTERMODE can then be determined, followed by CAP_PRINTERSTRING and CAP_PRINTERSUFFIX.

Scaling

ICAP_XSCALING should be negotiated before the ICAP_YSCALING.

Image Manipulation

ICAP_ROTATION is a specific request to the scanner to rotate the scanned image the indicated number of degrees. ICAP_MIRROR is another specific request to mirror the scanned image. ICAP_FLIPROTATION is used to properly orient images that flip orientation every other image.

General Capability Negotiation

ICAP_XFERMECH selects the way an image is transferred from the Source to an Application, which has an impact on some of the characteristics of an image, which is why this value must be selected first. If TWSX_NATIVE is selected, then no other action related to image transfer is needed. If TWSX_FILE is selected, then the application should negotiate ICAP_IMAGEFILEFORMAT, which will be used when DAT_SETUPFILEXFER is called. If TWSX_MEMORY is selected, then DAT_SETUPMEMXFER will need to be called. The Application may then opt to negotiate ICAP_TILES.

Then negotiate these capabilities… ICAP_PIXELTYPE

or ICAP_JPEGPIXELTYPE

Use of flash may affect other values… ICAP_FLASHUSED

ICAP_FLASHUSED

ICAP_AUTOBRIGHT

ICAP_BRIGHTNESS ICAP_BITDEPTH ICAP_BITDEPTHREDUCTION

ICAP_CUSTHALFTONE ICAP_HALFTONES ICAP_THRESHOLD

ICAP_BITORDER ICAP_COMPRESSION

ICAP_BITORDERCODES ICAP_CCITTKFACTOR ICAP_PIXELFLAVORCODES ICAP_TIMEFILL

ICAP_CONTRAST ICAP_EXPOSURETIME ICAP_FILTER ICAP_GAMMA ICAP_IMAGEFILTER ICAP_NOISEFILTER ICAP_PIXELFLAVOR

ICAP_HIGHLIGHT ICAP_SHADOW

ICAP_PLANARCHUNKY ICAP_XRESOLUTION

ICAP_XNATIVERESOLUTION ICAP_YRESOLUTION

ICAP_YNATIVERESOLUTION

Independent Capabilities

These capabilities are considered independent because they do not affect other capabilities and they are not affected by changes in other capabilities.

CAP_ENABLEDSUIONLY CAP_CUSTOMDSDATA CAP_INDICATORS CAP_INDICATORSMODE CAP_UICONTROLLABLE CAP_SERIALNUMBER ICAP_LAMPSTATE CAP_BATTERYMINUTES CAP_BATTERYPERCENTAGE CAP_POWERSUPPLY ICAP_BITORDER CAP_DEVICETIMEDATE CAP_DEVICEEVENT CAP_CAMERAPREVIEWUI CAP_POWERSAVETIME ICAP_AUTODISCARDBLANKPAGES ACAP_XFERMECH

Semi-Independent Capabilities

CAP_SHEETCOUNT

CAP_TIMEBEFOREFIRSTCAPTURE CAP_TIMEBETWEENCAPTURES

CAP_ALARMVOLUME

Semi Independent Capabilities are small groups that have no effect on the big picture, but do have their own pockets of dependencies.

CAP_ALARMS

CAP_AUTOMATICCAPTURE

CAP_XFERCOUNT ICAP_TILES ICAP_LIGHTPATH CAP_FILMTYPE CAP_DUPLEX CAP_DUPLEXENABLED

CAP_FEEDERORDER CAP_FEEDERALIGNMENT CAP_PAPERHANDLING ICAP_IMAGEMERGE ICAP_IMAGEMERGEHEIGHTTHRESHOLD CAP_FEEDERPOCKET CAP_FEEDERPREP CAP_AUTOFEED

CAP_CLEARPAGE CAP_FEEDPAGE CAP_REWINDPAGE CAP_PAPERDETECTABLE CAP_FEEDERLOADED CAP_AUTOMATICSENSEMEDIUM ICAP_LIGHTSOURCE ICAP_FEEDERTYPE ICAP_DOUBLEFEEDDETECTION

CAP_DOUBLEFEEDDETECTIONLENGTH CAP_DOUBLEFEEDDETECTIONSENSITIVITY CAP_DOUBLEFEEDDETECTIONRESPONSE CAP_FEEDERENABLED CAP_CUSTOMINTERFACEGUID CAP_SUPPORTEDCAPS CAP_EXTENDEDCAPS ICAP_SUPPORTEDEXTIMAGEINFO CAP_LANGUAGE CAP_DEVICEONLINE ICAP_XFERMECH CAP_MICRENABLED CAP_IMAGEADDRESSENABLED CAP_PRINTER ICAP_UNITS ICAP_IMAGEDATASET

ICAP_XNATIVERESOLUTION ICAP_YNATIVERESOLUTION ICAP_PHYSICALWIDTH ICAP_PHYSICALHEIGHT ICAP_MINIMUMHEIGHT ICAP_MINIMUMWIDTH CAP_THUMBNAILSENABLED CAP_PRINTERCHARROTATION CAP_PRINTERFONTSTYLE CAP_PRINTERSTRING CAP_PRINTERINDEXLEADCHAR CAP_PRINTERINDEXNUMDIGITS CAP_PRINTERINDEXMAXVALUE CAP_PRINTERINDEXSTEP CAP_PRINTERINDEX CAP_PRINTERSUFFIX CAP_PRINTERINDEXTRIGGER CAP_PRINTERSTRINGPREVIEW

CAP_PRINTERMODE CAP_PRINTERVERTICALOFFSET CAP_PRINTERENABLED

CAP_IAFIELDA_LEVEL CAP_IAFIELDB_LEVEL CAP_IAFIELDC_LEVEL CAP_IAFIELDD_LEVEL CAP_IAFIELDE_LEVEL CAP_IAFIELDA_PRINTFORMAT CAP_IAFIELDB_PRINTFORMAT CAP_IAFIELDC_PRINTFORMAT CAP_IAFIELDD_PRINTFORMAT CAP_IAFIELDE_PRINTFORMAT CAP_IAFIELDA_VALUE CAP_IAFIELDB_VALUE CAP_IAFIELDC_VALUE CAP_IAFIELDD_VALUE CAP_IAFIELDE_VALUE

* If CAP_THUMNAILSENABLED is enabled, do not negotiate any further capabilities related to dimensions of the output image. This capability over-rides all in order to have the Source deliver reasonable thumb- ICAP_AUTOMATICCOLORENABLED ICAP_AUTOMATICCOLORNONCOLORPIXELTYPE nail images. ICAP_COLORMANAGEMENTENABLED CAP_CAMERASIDE ICAP_AUTOBRIGHT ICAP_BRIGHTNESS

ICAP_PIXELFLAVOR ICAP_PLANARCHUNKY ICAP_BITDEPTHREDUCTION

ICAP_CUSTHALFTONE ICAP_HALFTONES ICAP_THRESHOLD ICAP_IMAGEFILEFORMAT ICAP_XFERMECH ICAP_BITORDERCODES ICAP_CCITTKFACTOR ICAP_PIXELFLAVORCODES ICAP_TIMEFILL ICAP_JPEGPIXELTYPE ICAP_JPEGQUALITY ICAP_JPEGSUBSAMPLING ICAP_PIXELTYPE ICAP_BITDEPTH

ICAP_XRESOLUTION ICAP_YRESOLUTION ICAP_COMPRESSION *Available Compressions are also directly dependent upon the current setting of ICAP_XFERMECH.

CAP_CAMERAENABLED CAP_CAMERAORDER ICAP_ICCPROFILE

ICAP_XSCALING ICAP_YSCALING ICAP_ZOOMFACTOR ICAP_CONTRAST ICAP_GAMMA ICAP_HIGHLIGHT ICAP_SHADOW ICAP_EXPOSURETIME ICAP_FILTER ICAP_IMAGEFILTER ICAP_NOISEFILTER ICAP_SUPPORTEDSIZES ICAP_MAXFRAMES ICAP_ORIENTATION CAP_AUTHOR CAP_CAPTION CAP_TIMEDATE ICAP_FLASHUSED obsolete ICAP_FLASHUSED ICAP_UNDEFINEDIMAGESIZE CAP_AUTOSCAN

CAP_XFERCOUNT CAP_SHEETCOUNT CAP_MAXBATCHBUFFERS CAP_REACQUIREALLOWED

ICAP_FLIPROTATION ICAP_ROTATION ICAP_MIRROR ICAP_FRAMES

ICAP_AUTOSIZE ICAP_AUTOMATICCROPUSESFRAME ICAP_AUTOMATICLENGTHDETECTION ICAP_AUTOMATICBORDERDETECTION ICAP_AUTOMATICDESKEW ICAP_AUTOMATICROTATE ICAP_OVERSCAN CAP_SEGMENTED  ICAP_BARCODEMAXSEARCHPRIORITIES ICAP_PATCHCODEDETECTIONENABLED ICAP_EXTIMAGEINFO ICAP_BARCODEDETECTIONENABLED

CAP_ENDORSER CAP_JOBCONTROL ICAP_BARCODESEARCHPRIORITIES ICAP_SUPPORTEDBARCODETYPES

ICAP_BARCODESEARCHMODE ICAP_BARCODEMAXRETRIES ICAP_BARCODETIMEOUT ICAP_PATCHCODESEARCHPRIORITIES ICAP_PATCHCODEMAXSEARCHPRIORITIES ICAP_SUPPORTEDPATCHCODETYPES

ICAP_PATCHCODESEARCHMODE ICAP_PATCHCODEMAXRETRIES ICAP_PATCHCODETIMEOUT

Audio Negotiation

The availability of the audio capabilities can be inferred from the presence of DG_AUDIO. If it is available then the Application should negotiate ACAP_XFERMECH. Note that these operations occur independently of the current value of DAT_XFERGROUP. The actual selection of an audio file format takes place in State 6 using DAT_SETUPFILEXFER, and must be preceded by a call to DAT_XFERGROUP / MSG_SET to DG_AUDIO to change the Source over to the audio data group. Sources that transfer audio data need to set the Source back to DG_IMAGE when they are done with the audio data, and ready to get image data, or exit back to State 4.

Alarms

CAP_ALARMS selects the kind of audio alerts provided by a Source. CAP_ALARMVOLUME is only available if an alarm is selected, and controls the volume for all alarms with a single value.

Power Supply

CAP_POWERSUPPLY reports which power supply is currently in effect for the Source. CAP_BATTERYPERCENTAGE, CAP_BATTERYMINUTES and CAP_POWERSAVETIME are available at all times, though the values they report may change depending on the current value of CAP_POWERSUPPLY.

Asynchronous Device Events

CAP_DEVICEEVENT may be used to activate device events.

Automatic Capture

DG_CONTROL / DAT_FILESYSTEM / MSG_AUTOMATICCAPTUREDIREDCTORY should be negotiated first, since it selects the destination for the images. CAP_TIMEBEFOREFIRSTCAPTURE and CAP_TIMEBETWEENCAPTURES should be negotiated next. CAP_AUTOMATICCAPTURE must be negotiated last, because it is the trigger that starts the timer.

Camera-Dependent Capabilities

The following list covers capabilities have no interdependencies, but which may be dependent on the currently selected device (for Sources that support DAT_FILESYSTEM).

CAP_AUTHOR CAP_CAMERASIDE CAP_CAPTION CAP_DEVICETIMEDATE CAP_ENDORSER CAP_JOBCONTROL CAP_PASSTHRU CAP_SERIALNUMBER CAP_SHEETCOUNT CAP_TIMEDATE CAP_XFERCOUNT CAP_INDICATORSMODE ICAP_EXTIMAGEINFO ICAP_IMAGEDATASET ICAP_LAMPSTATE ICAP_LIGHTPATH ICAP_LIGHTSOURCE ICAP_ZOOMFACTOR

Camera-Independent Capabilities

The following list covers capabilities that are free of any dependencies. Applications can negotiate these in any order (during state 4), and regardless of the current device in effect (for Sources that support DAT_FILESYSTEM):

CAP_CAMERAPREVIEWUI CAP_CUSTOMDSDATA

CAP_DEVICEONLINE CAP_DEVICETIMEDATE CAP_ENABLEDSUIONLY CAP_INDICATORS CAP_PASSTHRU CAP_SEGMENTED CAP_SHEETCOUNT CAP_THUMBNAILSENABLED CAP_TIMEDATE CAP_UICONTROLLABLE CAP_XFERCOUNT

Defaults

TWAIN describes defaults for capabilities, unfortunately, this information is spread throughout the specification, and in some cases is ambiguous. This article discusses how Sources and Applications should use and manage defaults values. It covers the three main kinds of defaults supported by TWAIN. It discusses the DG_CONTROL / DAT_CAPABILITY / MSG_xxxx functions and how they relate to defaults. Finally, it offers a section that describes the expected default settings for each capability within TWAIN.

Default Mechanisms

Defaults in TWAIN serve three main functions: Mandatory Defaults Protect Applications from incompatible settings.

Preferred Defaults Permit Source providers to expose preferred settings for capabilities.

User Defaults Create consistency in a Source’s user interface; values selected in one session are preserved for the next session.

Mandatory defaults are established by the TWAIN specification. Preferred defaults may be selected by a Source for any capability that does not have a mandatory default. User defaults may replace any preferred default with a value selected by the user through the Source’s user interface. These three functions are not intrinsically compatible, which creates ambiguity; Applications cannot make assumptions about the initial values of all capabilities.

Mandatory Defaults

Some capabilities must reflect certain values when a Source is opened. These defaults are selected because Applications must be allowed to expect certain kinds of behavior without being forced to negotiate all capabilities (not only would this be tedious, but it is impossible in situations where a Source and Application are derived from different versions of TWAIN). For example, the 1.8 capability CAP_PRINTERENABLED must default to FALSE, otherwise a 1.6 Application might find itself printing data on scanned documents, and unable to do anything about it.

Preferred Defaults

TWAIN permits a Source to provide its own defaults. These settings are assumed to produce the most favorable results possible, whether they are measured in terms of processing speed, memory usage, or some other criteria. For instance, a Source will select a preferred value for ICAP_PIXELFLAVOR that keeps it from having to invert the bits in an image. In some cases the preferred defaults are gleaned from the current state of the device. For instance, CAP_FEEDERENABLED depends on the presence of a feeder on the scanner device. A Source is expected to determine if the feeder is truly present, not assume that the value saved from the last session is valid.

User Defaults

Prior to TWAIN 1.7 Applications generally relied on Sources to provide user interfaces that controlled image capture. Since one of the tenants of TWAIN is to make things easier for Applications, it became common for Sources to save state, preserving the values selected by a user, so the next time the Application started the same values would be displayed. This mechanism continues to be desirable, but Source writers should bear in mind that user defaults values are a convenience that can create problems for users who access their Source from more than one Application. CAP_AUTOSCAN is an example of a capability that should never have its state saved, since Applications that do not negotiate will also not be able to handle the results if it happens to be set to TRUE.

DAT_CAPABILITY Operations

There are five methods of negotiating values with a Source, this section discusses how Sources and Applications should relate them to the various kinds of default values: MSG_GET returns the current value of the capability, along with the allowed values (if any). At startup, this value will reflect the mandatory default, if there is one. If there is no mandatory default, then this call will return the user default, if supported and if one is available; otherwise it will return the preferred default value for the Source. It is up to the Application to understand the possible sources of a value, and override it if desired. Note that the allowed values are always reset when a Source starts up. Sources must never save the constraints created by an Application.

MSG_GETCURRENT returns the current value of the capability, it does not return the allowed list. At startup, this value will reflect the mandatory default, if there is one. If there is no mandatory default, then this call will return the user default, if supported and if one is available; otherwise it will return the preferred default value for the Source.

MSG_GETDEFAULT always returns either the mandatory or preferred default, whichever is appropriate for the capability. It never returns a user default. Like MSG_GETCURRENT it only returns the value, not the allowed list.

MSG_RESET resets a capability’s allowed list to all permitted values, and sets the current value to the mandatory or preferred default, never the user default. The container returned by MSG_RESET must be the same kind of container returned for a MSG_GETDEFAULT operation, this preserves legacy behavior; however, Applications should follow MSG_RESET with MSG_GET if they wish to determine how the constraints for the capability have been reset.

This message is a good one for Applications to use, since it is easy to code, and can be used to get a Source to some kind of a known state.

A simple mechanism for resetting a Source uses the following steps (Applications that use the Source’s UI should not use this method): for each device supported by the Source (pre-1.8 Sources only have one implicit device) the Application calls CAP_SUPPORTEDCAPS; for each capability the Application calls DG_CONTROL / DAT_CAPABILITY / MSG_QUERYSUPPORT to see if it supports TWQI_RESET; if it does, then the Application sends DG_CONTROL / DAT_CAPABILITY / MSG_RESET which resets the capability. Performing these steps will protect an Application from any user defaults created by a previous Application. Please note, not all Sources may support MSG_QUERYSUPPORT. For those that don’t, an Application would have to issue MSG_RESET on all capabilities (perhaps excluding those it knows to be read-only) and trust that the Source is robust enough to report TWRC_FAILURE for those capabilities that do not support MSG_RESET. MSG_SET sets the current value. Therefore, it’s possible for a capability set in State 4 to find its way into the user defaults.

MSG_SETCONSTRAINT sets the current value and optionally sets the constraints on a capability. Sources must never save the constraints negotiated by an application. However, it’s possible for a capability set in State 4 to find its way into the user defaults. B TWAIN Technical Support

If you have a question or technical issue that isn't answered on the TWAIN.org website, ask the TWAIN community at http://twainforum.org The TWAIN Forum is an online discussion platform where you can exchange ideas with the TWAIN community. We suggest reviewing previous messages in the forum or posting a new message for best results to technical questions As an alternative, contact TWAIN directly at admin@twain.org.

TWAIN Notice

Where would you like to scan from? Scan in Web Apps Scan in Java Scan in .NET