Kodak KDS TWAIN Driver
Getting Started
20-June-2012
Contents
1. Overview...................................................................................................................... 2
2. GUI Based Applications (the old way)........................................................................... 3
3. Programmatic Based Applications (the newer way)........................................................ 4
4. Profile Based Applications (the best way)...................................................................... 5
5. Decoupling.................................................................................................................... 6
6. Logging and the Simulator.............................................................................................. 7
7. Sample Code................................................................................................................ 8
Developing an application using any image capture application programming interfaces (API) is a challenge. The basic premise of these systems is that the application discovers a device through its driver, interrogates it about its capabilities, sets a session up, and then starts scanning. The problem is that there are a large number of capabilities all interacting in a variety of ways (some obvious and some not), so that getting the driver to do exactly what is desired is not always as straightforward as could be hoped. And, as with any API, things usual work well until errors are encountered, then the amount of code increases dramatically to accommodate all the possible results for any given operation.
TWAIN provides ways to mitigate this work, though it may not be obvious from reading the specification. This document will outline some development strategies designed to create robust, flexible applications. It is assumed that the reader has some familiarity with TWAIN, either from previous coding experience or from reading some of the TWAIN specification.
When TWAIN was developed in the early 1990’s the single focus of the effort was to bring applications and drivers together. Previously an application writer would select a device, like a flatbed scanner, get the driver for it and write the application code to talk to that device. Support for a new device meant getting its driver and writing code to support it as well. TWAIN was designed to abstract away that driver code, hiding it behind a common API. Now it was possible for an application to start scanning and capture image data in a way that worked for any device the came with a TWAIN driver.
There was one area that the standard did not try to handle at first, and that was capability negotiation. True, TWAIN came with a selection of programmatic capabilities, so that it was possible to negotiate some kinds of values, but the selection was small. Instead drivers came with internally generated dialogs. The application invoked these dialogs and left all the problems of negotiation to the driver. The benefit was that an application could realize the full functionality of a device while writing very little code. The problem was that scanner vendors all had very different ideas about what these dialogs should look like, so a user moving from using one scanner to another was very likely to end up working with a very different user interface.
Beginning with version 1.7 of the TWAIN specification and continuing through 1.8 and 1.9 an attempt has been made to allow for more sophisticated support of scanner capabilities. In fact the TWAIN specification doubled in size going from 1.7 to 1.8. The original 1.5 description of TWAIN allowed for the following kinds of things: standard and custom capability definitions, capabilities using a variety of container types (enumerations and ranges among them), self-descriptive data types (integers, strings, etc…), and access modes (read-only, read-write, etc). 1.8 introduced the ability to independently address the image generating devices (for instance the front and rear cameras, or the color and bitonal cameras). It made it possible to write applications that could drive most or all of the features of a scanner without resorting to the custom user interface provided by the driver.
The problem was that most driver writers created their drivers for specific applications and since these applications didn’t significantly exercise the programmatic interface, the drivers often did not perform well when accessed in this way. Improvements in the testing documentation and the basic specification, and the stated desire from applications writers has resulted in better programmatic drivers, but that still leaves another problem.
Programmatic interfaces must reflect the abilities of their drivers. They must constrain possible values as dictated by the device, and they must prevent illegal combinations of functionality. What this means is that an application may not be limited to just asking what the allowed values are in a range or an enumeration. If the application is currently negotiating on a color camera, then ICAP_THRESHOLDING may not be available until the camera context is changed to bitonal. If the ICAP_XFERMECH is set to allow native mode transfers (bitmaps on Windows systems) then ICAP_COMPRESSION may only report a possible value of “none”. So the application has to conduct inquiries on permutations of settings within the driver.
The benefit to all this hard work is that the application can present a single unified interface to the user, regardless of the physical device currently in use, which means that end users do not need to be retrained (save maybe for basic functional differences) anytime they operate a new scanner with the application. Over the past several years more and more application writers have been opting to rely on programmatic control, or in some cases a combination of programmatic control for the most commonly used features with the ability to raise the driver GUI for the more rarely used features.
There is a third alternative that was introduced with little fanfare in the TWAIN 1.7 specification. The operation DAT_CUSTOMDSDATA (if supported) can be used to take a snapshot of the current state of the driver. It can also be used to restore the settings of the driver using one of these snapshots. 1.7 also introduced the concept of a “settings only” TWAIN GUI through the DG_CONTROL / DAT_USERINTERFACE / MSG_ENABLEDSUIONLY. In this mode the user can set whatever features they want from the TWAIN supplied GUI, but their only finishing option is to select OK or CANCEL.
The application writer creates two programs. One program raises the TWAIN GUI, allows the user to set whatever values they want, then when OK is hit takes a snapshot of the driver using DAT_CUSTOMDSDATA and saves the result in a file tagged with some useful name or description from the user, like “photo settings” or “insurance form settings.” The second program is the scanning application, but all it presents to the user is a list of these snapshot or profile descriptions. So the user selects “photo settings,” the application reads that file from disk, sends the data to the driver using DAT_CUSTOMDSDATA, and begins scanning. Note that it is still possible to raise the GUI or to programmatically negotiate values; the intention is to minimize that need.
In this way we get full access to the features of the device without writing a lot of code, and protect the scanner operator from having to be retrained anytime a new scanner shows up. All of the Kodak Document Scanners (5000/7000/9000/3000/4000/i30/i40/i200/i600/i800/i900/i1100/i1200/i1300/i1400/i1800/i2000/i2900/i3000/i4000/i5000) support this command. Most application writers should give serious thought to using this technique to drive their scanner.
One of the most powerful features in TWAIN is its ability to totally decouple the negotiation phase (state 4/5) from the image capture phase (state 6/7). From the earliest versions of the scanner the application writer has been encouraged to look at the bitmap information for a native transfer, the header information for a file transfer, or the DAT_IMAGEINFO information for a memory transfer. Starting with version 1.7 and continuing with 1.8 and 1.9 of the TWAIN specification we have supported the DAT_EXTIMAGEINFO command, which allows for the collection of a block of metadata associated with an image.
The gist of it is: never assume that what was negotiated is what is going to be captured by the scanner. This applies to the following items (there may be more): ICAP_AUTOMATICBORDERDETECTION (custom ICAP_CROPPINGMODE), ICAP_AUTOMATICDESKEW, and ICAP_PIXELTYPE and all related capabilities (when using the color toggle patch). The application should be ready for anything to come from the scanner. That does not mean it has to accept the data it is receiving, if it cannot handle a color image when waiting for a bitonal image, then it should throw an error to the user. However, the application should not ASSUME that the data coming from the scanner is exactly what it negotiated. If an application obeys this basic rule of decoupling then it will be never be surprised by the behavior of the scanner in a way that results in a failure or a crash.
Other documents in this kit talk about both of these items. The purpose of this section is to show how they can be used to aid in development. When first writing an application for a Kodak Document Scanner it might be helpful to see some of the activity that occurs through TWAIN while the device is being driven by another application.
The Scanner Validation Tool (SVT) is not necessarily the best application in the world for this kind of work, but at least it is something. If you go into the CONST.INI file and turn on debugging so that it traces the TWAIN activity:
; Versions 2/3/4
Debug=1
DebugFilter=kdscaps kdsdat
; Version 5+
Debug=1
DebugFilter=TWAIN
Then when you run the SVT the driver will generate a log of all the activity that takes place between it and the application. This information is written using TWAIN constants that can be found in the specification and in the TWAIN.H file. Use this information to understand what is being done to setup the driver and capture the images. Please note that SVT is a GUI Based Application (in fact it is a diagnostic tool), so it’s not very sophisticated in its ability to programmatically negotiate settings. It is, however, very sophisticated in its ability to drive the scanner to its maximum throughput speeds. It also has a variety of error handling abilities, so it responds well to jams and multifeeds, among the other things that can happen.
You can use the simulator to get exactly the same results you would with a real scanner, which is especially useful for testing against all the varied models supported by the driver.
The TWAIN Working Group website (www.twain.org) has sample application code. We will include any sample code with this kit as it seems appropriate.