### What is this repository for? ###

* This repository contains the DTWAIN Library, **Version 5.x**, from Dynarithmic Software.  DTWAIN is an open source programmer's library that will allow applications to acquire images from TWAIN-enabled devices using a simple Application Programmer's Interface (API).

* The Dynarithmic TWAIN Library is open source and licensed under the Apache 2.0 License.  Please read the [LICENSE](https://github.com/dynarithmic/twain_library/tree/master/LICENSE) file for more information.
* The DTWAIN Library online help file can be found [here](https://www.dynarithmic.com/onlinehelp/dtwain/newversion/Dynarithmic%20TWAIN%20Library,%20Version%205.x.html), and in .CHM (Windows Help) format [here](https://github.com/dynarithmic/twain_library-helpdocs/tree/main/windows).  

    The .CHM file and online-help are being updated to version 5.x on a constant basis.  Updates will be made available in the [help repository](https://github.com/dynarithmic/twain_library-helpdocs/tree/main), as it may have information that pertains to the older commercial version of DTWAIN that will have to be updated or removed.
* The current version of DTWAIN is [**5.8.2** (See Version History)](https://github.com/dynarithmic/twain_library/tree/master/updates/updates.txt).

**Please note that the source code and sample programs for the Dynarithmic TWAIN Library has moved to [this repository](https://github.com/dynarithmic/twain_library_source/tree/main)**.

----

### Ok, so what is this Dynarithmic TWAIN library, or "DTWAIN" as you call it? ###

* The Dynarithmic TWAIN Library (also known as DTWAIN) is an open source, powerful programmer's library that will allow you to easily integrate TWAIN image acquisition from any TWAIN scanner or digital camera into your applications.  

* DTWAIN is implemented as a 32-bit and 64-bit Windows Dynamic Link Library (DLL), and to communicate with the DLL, exported functions are provided.  This allows any Windows-based computer language that can call exported DLL functions (directly or indirectly) to be able to use DTWAIN.  This includes C, C++, C#, Visual Basic, Python, Delphi, Lua, Java, Ruby, Rust, Go, F#, and numerous other languages.

* If you are not familiar with the TWAIN standard and image acquisition from TWAIN-enabled devices, please head to the official TWAIN website at [http://www.twain.org](http://www.twain.org) for more information.  If you've ever bought or used a scanner, and came across the words "TWAIN compliant" or "TWAIN driver", well you're on the right track.  If you're interested in getting these devices to work in your **C, C++, C#, D, Delphi, F#, Lua, Java, Visual Basic, Perl, Python, Ruby, Rust, Go** (and other languages) application, you've come to the right place.  

* The DTWAIN library relieves the programmer of having to get into the details of writing low-level code that follows the TWAIN specification to retrieve images from a TWAIN device -- just a few function calls to initialize and acquire images from the TWAIN device is all that's required.  

(There is nothing wrong with understanding the TWAIN specification, as this will enhance your knowledge of how the DTWAIN library works internally.  However the high-level of abstraction of the TWAIN protocol makes this library simple for even the novice programmer to use).

----------
### Is DTWAIN 5.x really Open Source Software (OSS)? 
 
* The Dynarithmic® TWAIN Library has been developed over the course of 20 years, so this is a very mature software component.  We have offered this library as a closed source, commercial product over those years, however we have decided to make this library open source under the Apache 2.0 license.    

* Please note -- since DTWAIN prior to version 5.0 used source code in some modules that could not be released to the general public due to licensing issues, we had to revamp these portions of the codebase so as to allow DTWAIN to become an open source library.  We have made all strives to make sure that these changes to DTWAIN will not cause issues, but as most of you know, bugs can exist.  If bugs are found, we will be addressing them in a short manner.

----------

### Preliminaries

DTWAIN is supported under *Windows 10 / Windows 11 for both 32-bit and 64-bit operating systems. Since the base libraries are built to support the Visual C++ runtime library, version 2015 and above, the minimum version of the Visual C++ runtime that is supported is **Visual C++ 2015**.  

*There is no official support for Windows 7 / Windows 8.x, as newer versions of DTWAIN are only tested for Windows versions 10 and 11.  Note that this is not to say that DTWAIN will not work for Windows 7 / 8, but it hasn't been tested with these operating systems for the past few years.  If you require support for Windows 7 or 8, please open an [issue](https://github.com/dynarithmic/twain_library/issues) to see if this can be addressed.

----

The "standard" versions of the DTWAIN library ("standard" meaning the DLL's found in the **full_logging** and **partial_logging** directories -- See below in the **How do I get set up using DTWAIN** section) will not require an installation of the Visual C++ runtime files, so there shouldn't be an issue when using the standard versions.  However the standard versions are larger in size (up to a megabyte or so) than the versions that require an installation of the Visual C++ runtime already installed on the system that DTWAIN will be running on.

Since most Windows systems within the past 8 years has the Visual C++ runtime already installed by other applications, this may not be an issue and the smaller-sized DTWAIN DLL's can be used.  However, if for some reason your system does not have the proper runtime components, you can get the Visual C++ runtime libraries <a href="https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#latest-microsoft-visual-c-redistributable-version" target="_blank">here</a>.  When downloading, choose **vc_redist.x86.exe** for 32-bit applications, and/or **vc_redist.x64.exe** for 64-bit applications.

----------
### I don't have a TWAIN device or scanner installed on my system.  How do I work with DTWAIN?
There are sample virtual TWAIN devices [found here](https://github.com/dynarithmic/twain_virtual-drivers).  Once installed, these devices will be available for selection for acquiring images, similar to an installed scanner.

----------
----

### How do I get set up using DTWAIN? ###
----
**<u>Building the DTWAIN application</u>**

<a name="dtwaindllusage"></a>
For 32-bit applications, use the binaries found in **release_libraries.zip** in one of the following directories:

[full_logging](https://github.com/dynarithmic/twain_library/tree/master/binaries/32bit/full_logging) with checksums found here: [checksum values](https://github.com/dynarithmic/twain_library/blob/master/binaries/32bit/full_logging/release_ziphashes32.txt)</br>
[partial_logging](https://github.com/dynarithmic/twain_library/tree/master/binaries/32bit/partial_logging) with checksums found here: [checksum values](https://github.com/dynarithmic/twain_library/blob/master/binaries/32bit/partial_logging/release_ziphashes32.txt)</br>
[full_logging_require_vcruntime](https://github.com/dynarithmic/twain_library/tree/master/binaries/32bit/full_logging_require_vcruntime) with checksums found here: [checksum values](https://github.com/dynarithmic/twain_library/blob/master/binaries/32bit/full_logging_require_vcruntime/release_ziphashes32.txt)</br>
[partial_logging_require_vcruntime](https://github.com/dynarithmic/twain_library/tree/master/binaries/32bit/partial_logging_require_vcruntime) with checksums found here: [checksum values](https://github.com/dynarithmic/twain_library/blob/master/binaries/32bit/partial_logging_require_vcruntime/release_ziphashes32.txt)</br> 

----

For 64-bit applications, use the binaries found in **release_libraries.zip** in one of the following directories:

[full_logging](https://github.com/dynarithmic/twain_library/tree/master/binaries/64bit/full_logging) with checksums found here: [checksum values](https://github.com/dynarithmic/twain_library/blob/master/binaries/64bit/full_logging/release_ziphashes64.txt)</br>
[partial_logging](https://github.com/dynarithmic/twain_library/tree/master/binaries/64bit/partial_logging) with checksums found here: [checksum values](https://github.com/dynarithmic/twain_library/blob/master/binaries/64bit/partial_logging/release_ziphashes64.txt)</br>
[full_logging_require_vcruntime](https://github.com/dynarithmic/twain_library/tree/master/binaries/64bit/full_logging_require_vcruntime) with checksums found here: [checksum values](https://github.com/dynarithmic/twain_library/blob/master/binaries/64bit/full_logging_require_vcruntime/release_ziphashes64.txt)</br>
[partial_logging_require_vcruntime](https://github.com/dynarithmic/twain_library/tree/master/binaries/64bit/partial_logging_require_vcruntime) with checksums found here: [checksum values](https://github.com/dynarithmic/twain_library/blob/master/binaries/64bit/partial_logging_require_vcruntime/release_ziphashes64.txt)</br> 


----

The **full_logging** directory contains the DLL's that have the following characteristics: 
1) Built with full logging capabilities. Full logging consists of logging the call stack and return values when calling DTWAIN functions, plus the lower level calls that DTWAIN makes to the TWAIN Data Source Manager.  This is valuable in detecting issues that may occur when issuing calls to DTWAIN.
2) Does not require an installation of the Visual C++ Runtime on the target system.

The **partial_logging** directory contains the DLL's that are:
1) Built without call stack and return values being logged.  These DLL's are around 500K smaller in size than the DLL's in **full_logging**.  Direct calls to the lower level TWAIN DSM are included, but the call stack and return value logging is not available, and
2) Does not require an installation of the Visual C++ Runtime on the target system.

The **full_logging_require_vcruntime** directory contains the DLL's that are 
1) Built with full logging capabilities, exactly the same as **full_logging** described above, and
2) Requires an installation of the Visual C++ Runtime on the target system.

The **partial_logging_require_vcruntime** directory contains the DLL's that are 
1) Built without call stack and return values being logged, exactly the same as **partial_logging** described above, and
2) Requires an installation of the Visual C++ Runtime on the target system.

If you are not concerned with sizes of the DLL's, the **full_logging** DLL's should be used.  If you desire DLL's that are a bit smaller and can "sacrifice" call stack / return value logging, the **partial_logging** DLL's should be used.  

If you will install the Visual C++ Runtime yourself, or assume that the systems you will run DTWAIN on have the Visual C++ Runtime already installed, you can use the DLL's in the "*_require_vcruntime" directories, further reducing the size of the DTWAIN DLL's being used.

To distinguish between whether the full or partial logging DLL's are in use (since the names of the DTWAIN DLL's themselves are the same, regardless of which ones are used), see [the following information](https://github.com/dynarithmic/twain_library_source/tree/main/binaries/32bit#how-to-distinguish-between-full-and-partial-logging-dlls).

In addition, the [release version of the Program Database (.PDB) files](https://github.com/dynarithmic/dtwain-pdb) are available.  This will aid in debugging any issues involving DTWAIN.

----

A breakdown of the files contained in **release_libraries.zip** is as follows:

    dtwain32.dll   --  32-bit ANSI (MBCS) Dynamic Link Library
    dtwain32u.dll  --  32-bit Unicode Dynamic Link Library
    dtwain32.lib   --  32-bit ANSI (MBCS) Visual C++ import library
    dtwain32u.lib  --  32-bit Unicode Visual C++ import library
    dtwain32.pdb   --  32-bit PDB (Microsoft debug) files for dtwain32.dll
    dtwain32u.pdb  --  32-bit PDB (Microsoft debug) files for dtwain32u.dll

    dtwain64.dll   --  64-bit ANSI (MBCS) Dynamic Link Library
    dtwain64u.dll  --  64-bit Unicode Dynamic Link Library
    dtwain64.lib   --  64-bit ANSI (MBCS) Visual C++ import library
    dtwain64u.lib  --  64-bit Unicode Visual C++ import library
    dtwain64.pdb   --  64-bit PDB (Microsoft debug) files for dtwain64.dll
    dtwain64u.pdb  --  64-bit PDB (Microsoft debug) files for dtwain64u.dll

Please note that the files with the "u" in the name are Unicode aware.  If your application requires Unicode-based string processing, it is always best to use the "u" versions of the above files.  

For example, if you plan to use the [language text resources](https://github.com/dynarithmic/twain_library/tree/master-staging/additional_language_resources) that use UTF-8 character sequences that have issues displaying properly using the ANSI version of the library (for example, Greek), you should use one of the "u" DLL's listed above.  More info on the language text resources are found later in this README.

The DTWAIN API has available ANSI-aware functions even in the Unicode versions of the library, in the event your Unicode application needs to process ANSI strings.  This is usually done by the API function ends with "A", for example `DTWAIN_GetSourceProductNameA` for the ANSI version of the function `DTWAIN_GetSourceProductName`.  Similarly, there are Unicode or wide-character functions available for the ANSI version of the DLL's in the event your ANSI-based application needs to process wide/Unicode strings (for example `DTWAIN_GetSourceProductNameW` for the wide-character version of the function `DTWAIN_GetSourceProductName`).

----

###### Information for C and C++ programmers:

If you are using Visual C++, the Visual C++ compatible import libraries necessary to build your 32-bit or 64-bit application (the files with the *.lib extension) are available.<br><br> 
If you do not use Visual C++ but instead are using another brand of C++ compiler, see the [section on additional C++ compiler usage](#alternatecompilers) to alleviate the import library issues.  

You will also need to include the header files found in the [c_cpp_includes](https://github.com/dynarithmic/twain_library/tree/master/c_cpp_includes) directory when building your application.  Your build **INCLUDE** path should refer to these header files.

Basically, you just need to build your application and link it to one of the import libraries that matches the environment your application is targeted for.  For example, if the application you're developing is a 32-bit, Unicode-based application, you would use the **dtwain32u.lib** file to allow your C/C++ application to link without errors.

----
<a name="runningapplication"></a>
**<u>Running the application</u>**

After building your application, for your application to run successfully, you must make sure the DTWAIN dynamic link library itself is located somewhere on the system path, or in your application directory (there are other places where the DLL can be located, but that is beyond the scope of this introduction -- please refer to the following link:

[https://docs.microsoft.com/en-us/windows/desktop/dlls/dynamic-link-library-search-order](https://docs.microsoft.com/en-us/windows/desktop/dlls/dynamic-link-library-search-order)).

In addition to the DLL files, the <a href="https://github.com/dynarithmic/twain_library/tree/master/text_resources/twaininfo.txt" target="_blank">text resource file</a>, the <a href="https://github.com/dynarithmic/twain_library/blob/master/text_resources/dtwain32.ini" target="_blank">dtwain32.ini</a> for 32-bit applications, and <a href="https://github.com/dynarithmic/twain_library/blob/master/text_resources/dtwain64.ini" target="_blank">dtwain64.ini</a> for 64-bit applications </a> must also be available (by default, these files should reside in the same directory as the DLL files above, however as of version **5.2.0.2**, these files can reside in the directory specified by **DTWAIN_SetResourcePath**).  

If **twaininfo.txt** or the INI files are not found, corrupted, incorrect version, or some other issue that prevents these files from being loaded, you will receive the following message box displayed, with one or more reasons for the error listed:

![following error when running your application](/images/resource_error.jpg)

The error message will differ depending on the reason for the error.

Note: If your application wants to suppress the above message box, but still receive an error return code, your application should issue a call to the API function **DTWAIN_SysInitializeNoBlocking** instead of **DTWAIN_SysInitialize** (see the examples below -- simply change **DTWAIN_SysInitialize** to **DTWAIN_SysInitializeNoBlocking**).  

* Make sure that you are running the latest version of **twaininfo.txt**, as changes to this file can affect how your application will run when using future versions of DTWAIN.  The simplest way to ensure that you are running the latest version is to always get the latest **twaininfo.txt** file whenever you use a newer release of the DTWAIN DLL's.  

An internal check for the resource version is done by DTWAIN.  If DTWAIN detects that the resources are corrupted or out-of-date, **DTWAIN_SysInitialize** will return a NULL handle indicating an error.  

If **DTWAIN_SysInitialize** or **DTWAIN_SysInitializeNoBlocking** returns a 0 or null handle, you should call **DTWAIN_GetLastError** to get the error value.  In addition, you can call **DTWAIN_GetErrorString** with the error number to get a string description of the error.

----

In addition, there are [optional string resource files available](https://github.com/dynarithmic/twain_library/tree/master-staging/additional_language_resources).  These files allow you to customize the language used when DTWAIN logs or reports errors.  Note that these files are loaded only after **DTWAIN_SysInitialize** or **DTWAIN_SysInitializeNoBlocking** returns without error.

These files should be placed in the same directory as the **twaininfo.txt** file and INI files.

If you want to use a different resource file or even add your own language resource, it is recommended you copy the file in question, rename the file, make the changes required, and then utilize the new file by calling the **DTWAIN_LoadCustomStringResources** API function.  

More detailed instructions on adding your own resource file can be found <a href="https://github.com/dynarithmic/twain_library/tree/master/additional_language_resources" target="_blank">here</a>.

----------
### Ok, how about a code sample?
The simplest example is probably one that opens the TWAIN "Select Source" dialog, allows the user to choose the TWAIN device.  Once chosen, the device acquires an image and saves the image as a BMP file named "Test.bmp".  Here is an entire C++ example that demonstrates this:

    #include <iostream>
    #include "dtwain.h"

    int main()
    {
        // display DTWAIN version, just for fun
        std::cout << "Hello to DTWAIN " << DTWAIN_VERINFO_FILEVERSION << "\n";

        // initialize the DTWAIN DLL
        DTWAIN_SysInitialize();
        
        // Show the "Select Source" TWAIN dialog box
        DTWAIN_SOURCE Source = DTWAIN_SelectSource();
        if ( Source ) // Will be non-zero if a Source is selected by the user
            // Acquire to a BMP file
            DTWAIN_AcquireFileA(Source, "Test.bmp", DTWAIN_BMP, DTWAIN_USENATIVE | DTWAIN_USENAME,
                                DTWAIN_PT_DEFAULT, DTWAIN_MAXACQUIRE, TRUE, TRUE, NULL);
        DTWAIN_SysDestroy();         
    }         

That's it.  

The program above displays the default "Select Source" dialog when choosing a Source.  This dialog is the dialog as defined by the TWAIN standard.  This dialog box cannot be "altered" or customized.

However, you can customize the "Select Source" dialog box by utilizing the dialog box resource defined in the DTWAIN DLL, and then utilize the `DTWAIN_SelectSource2()` function:

    #include <iostream>
    #include "dtwain.h"

    int main()
    {
        // display DTWAIN version, just for fun
        std::cout << "Hello to DTWAIN " << DTWAIN_VERINFO_FILEVERSION << "\n";

        // initialize the DTWAIN DLL
        DTWAIN_SysInitialize();
        
        // Show the "Select Source" with a custom title, 
        // centered on the current monitor, sort the names, and always have it at the topmost window
        DTWAIN_SOURCE Source = DTWAIN_SelectSource2A(NULL, "Custom Title", 0, 0,                      
                DTWAIN_DLG_CENTER_CURRENT_MONITOR | DTWAIN_DLG_SORTNAMES | DTWAIN_DLG_TOPMOSTWINDOW);
                
        if ( Source ) // Will be non-zero if a Source is selected by the user
            // Acquire to a BMP file
            DTWAIN_AcquireFileA(Source, "Test.bmp", DTWAIN_BMP, DTWAIN_USENATIVE | DTWAIN_USENAME,
                                DTWAIN_PT_DEFAULT, DTWAIN_MAXACQUIRE, TRUE, TRUE, NULL);
        DTWAIN_SysDestroy();         
    }         

----

If you desire to acquire to an image in memory instead of a file, that can be done also.  By default, a Windows-based TWAIN driver always returns a Device Independent Bitmap (DIB) as the memory image.    

    #include "dtwain.h"
    int main()
    {
        DTWAIN_SysInitialize();
        DTWAIN_SOURCE Source = DTWAIN_SelectSource();
        DTWAIN_ARRAY images;
        if ( Source )
        {
            images = DTWAIN_AcquireNative(Source, DTWAIN_PT_DEFAULT, DTWAIN_MAXACQUIRE, TRUE, TRUE, NULL);
            HANDLE hDib = DTWAIN_GetAcquiredImage(images, 0, 0); // handle to first DIB acquired is returned
            GlobalLock(hDib); // lock image
            /*Now our app has a DIB. We can do any function that needs a DIB
              This time, we'll just delete it.  Your app is responsible for deleting 
              the DIBs, since DTWAIN does not delete any DIBs generated 
              by the Source  */
            GlobalFree( hDib );
        }   
        DTWAIN_SysDestroy();         
    }         

The above assumes your application knows how to handle DIBs (they are basically BMP files).  Also note that the DTWAIN_GetAcquiredImage function takes three arguments.  The first is a "2 dimensional" array of images that were acquired, and the last two arguments denote the *acquisition number* and the *image number* in the acquisition (this technique is used to remember multipage acquisitions that occur without the user closing the device's user interface). 

----

In addition, you can acquire images without showing a user interface by simply specifying the "show user-interface" parameter to either TRUE (1), or FALSE (0).

    DTWAIN_AcquireFileA(Source, "Test.bmp", DTWAIN_BMP, DTWAIN_USENATIVE | DTWAIN_USENAME, 
                        DTWAIN_PT_DEFAULT, DTWAIN_MAXACQUIRE, FALSE, TRUE, NULL);

or if it is the second example:

    images = DTWAIN_AcquireNative(Source, DTWAIN_PT_DEFAULT, 
                                  DTWAIN_MAXACQUIRE, FALSE, TRUE, NULL);

----------

### What about setting device capabilities such as resolution, contrast, brightness, paper size, etc.?

Setting and getting device capabilities is an integral part of using a TWAIN-enabled device.  This is easily done by using the generic capability functions such as **DTWAIN_EnumCapabilities**, **DTWAIN_GetCapValues** and **DTWAIN_SetCapValues**, or one of the functions that wrap the setting of a capability such as **DTWAIN_SetResolution**, **DTWAIN_SetBrightness**, etc.

Here is an example of setting the ICAP_PIXELTYPE capability:

    #include "dtwain.h"
    int main()
    {
        DTWAIN_SysInitialize();
        DTWAIN_SOURCE Source = DTWAIN_SelectSource();
        if ( Source )
        {
            // set the pixel type to TWPT_RGB
            
            // First, create a DTWAIN_ARRAY to hold the value(s) we will set
            DTWAIN_ARRAY aPixelTypeValue = DTWAIN_ArrayCreateFromCap(Source, ICAP_PIXELTYPE, 0);
            
            // Add the TWPT_RGB value to our array of values
            DTWAIN_ArrayAddLong(aPixelTypeValue, TWPT_RGB);
            
            // Call function to set the ICAP_PIXELTYPE capability
            DTWAIN_BOOL result = DTWAIN_SetCapValues(Source, ICAP_PIXELTYPE, DTWAIN_CAPSET, aPixelTypeValue);
            
            if ( result )
            {
                // Capability was set
            }
            
            // Dispose of the array
            DTWAIN_ArrayDestroy(aPixelTypeValue);
        }   
        DTWAIN_SysDestroy();         
    }         


Here is an example of getting all of the available ICAP_PIXELTYPE values:

    #include <stdio.h>
    #include "dtwain.h"
    int main()
    {
        DTWAIN_SysInitialize();
        DTWAIN_SOURCE Source = DTWAIN_SelectSource();
        if ( Source )
        {
            // Get the pixel type values
            
            // First, declare a DTWAIN_ARRAY that will hold all the value(s) retrieved from the device
            DTWAIN_ARRAY aPixelTypeValues;
            
            // Call function to get all the ICAP_PIXELTYPE capabilities
            DTWAIN_BOOL result = DTWAIN_GetCapValues(Source, ICAP_PIXELTYPE, DTWAIN_CAPGET,                 &aPixelTypeValues);
            
            if ( result )
            {
                // Now array has all of the values.  Print each one:
                LONG numItems = DTWAIN_ArrayGetCount(aPixelTypeValues);
                LONG pixValue;
                for (int i = 0; i < numItems; ++i)
                {
                   DTWAIN_ArrayGetAtLong(aPixelTypeValues, i, &pixValue);                   
                   printf("Pixel Type value %d is %d\n", i+1, pixValue);
                }
                DTWAIN_ArrayDestroy(aPixelTypeValues);
            }               
        }   
        DTWAIN_SysDestroy();         
    }         


Here is an example that calls the high-level function DTWAIN_SetResolution that sets the resolution to 300 DPI.  Note that DTWAIN_SetResolution() is just a "shortcut" way of setting the `ICAP_XRESOLUTION` and `ICAP_YRESOLUTION` capabilities:

    #include "dtwain.h"
    int main()
    {
        DTWAIN_SysInitialize();
        DTWAIN_SOURCE Source = DTWAIN_SelectSource();
        if ( Source )
        {
            // set the resolution level to 300 dots-per-inch
            DTWAIN_SetResolution(Source, 300.0); 
            //...
        }   
        DTWAIN_SysDestroy();         
    }         
 
Of course, if the capability does not exist on the device, or if the values given to the capability are not supported (for example, if the device only supports 200 DPI and the function attempts to set the DPI to 300), the function returns FALSE and the error can be determined by calling **DTWAIN_GetLastError**.

In general, DTWAIN can set or get any capability, including custom capabilities that some manufacturers may support, and any future capabilities that may be added to the TWAIN specification.  

There are [other demo C and C++ programs](https://github.com/dynarithmic/twain_library/tree/master/demos/C_C++) that you can use to more advanced features of DTWAIN.

----------

<a name="alternatecompilers"></a>
### What if I am a C++ programmer, but I don't have Visual C++ as the compiler to use when building an application?  The Visual C++ import libraries will not work for me.  I use Embarcadero/g++/clang/MingW (fill in with your favorite compiler or IDE).  So how do I use the library?

You can do one of two things:

1. Attempt to convert the .lib files mentioned above to your compiler's version of an import library, or
2. Use dynamic library loading using the Windows API LoadLibrary, GetProcAddress, and FreeLibrary calls.  Usage of this method requires no import libraries to be used (which makes this a better choice).

For the first item, some compilers have external tools that allow you to use Visual Studio generated library files.  However, there still may be some quirks in those tools that do not create correct import libraries.  

For the second item, the [C/C++ dynamic bindings](https://github.com/dynarithmic/twain_library/blob/master/programming_language_bindings/C_CPP_DynamicLoad) should be used that easily facilitate usage of LoadLibrary, GetProcAddress, etc. without your application having to do the tedious and error-prone setup of function pointers, parameter types, return types, etc.  

----------

<a name="otherlanguages"></a>
### Wait...What about other computer languages?  Does this library only work for C and C++ applications? ###

DTWAIN will work with any computer language that can make calls to an external Windows DLL function.  The DTWAIN DLL's export all the API functions with a "C" interface and with the `__stdcall` calling convention (don't worry if you don't know about calling conventions -- basically all the Windows DLL's in your Windows installation have these properties, so DTWAIN is really no different than those other DLL's in terms of how you would call the exported functions).  

To utilize other computer languages, it still requires that one of the [DTWAIN dynamic link libraries (DLL)](#dtwaindllusage) is available at runtime that matches the environment (32-bit or 64-bit), and character set (ANSI, Unicode).  In addition the section on [running your application](#runningapplication) also applies.

DTWAIN includes computer language bindings and demo programs for the following computer languages found in the [programming language bindings](https://github.com/dynarithmic/twain_library/tree/master/programming_language_bindings) folder:

  [C and C++](https://github.com/dynarithmic/twain_library/tree/master/demos/C_C++) -- linking using Visual C++ compatible import libraries\
  [C and C++](https://github.com/dynarithmic/twain_library/tree/master/programming_language_bindings/C_CPP_DynamicLoad) -- using no import libraries.\
  [C#](https://github.com/dynarithmic/twain_library/tree/master/demos/C%23)\
  [D](https://github.com/dynarithmic/twain_library/tree/master/demos/D)\
  [Delphi](https://github.com/dynarithmic/twain_library/tree/master/demos/Delphi)\
  [F#](https://github.com/dynarithmic/twain_library/tree/master/demos/F%23)\
  [Go](https://github.com/dynarithmic/twain_library/tree/master/demos/Go)\
  [Java*](https://github.com/dynarithmic/twain_library-java)\
  [Lua (using LuaJit)](https://github.com/dynarithmic/twain_library/tree/master/demos/Lua)\
  [Perl](https://github.com/dynarithmic/twain_library/tree/master/demos/Perl)\
  [Python](https://github.com/dynarithmic/twain_library/tree/master/demos/Python)\
  [Ruby](https://github.com/dynarithmic/twain_library/tree/master/demos/Ruby)\
  [Rust](https://github.com/dynarithmic/twain_library/tree/master/demos/Rust)\
  [Visual Basic .NET](https://github.com/dynarithmic/twain_library/tree/master/demos/VisualBasic)\
  [XBase++ (Alaska Software)](https://github.com/dynarithmic/twain_library/tree/master/demos/XBase%2B%2B)

* Note: The Java interface is a full-featured implementation using DTWAIN, and has a dedicated repository found in [twain_library-java](https://github.com/dynarithmic/twain_library-java).

Other languages can be supported, as long as the language is capable of calling exported DLL functions.  The ones listed above have had proper interfaces to the exported functions already set up.

A full C# demo can be found <a href="https://github.com/dynarithmic/twain_library-csharp_demo" target="_blank">here</a>.

A full Visual Basic .NET demo can be found <a href="https://github.com/dynarithmic/twain_library-visualbasic_demo" target="_blank">here</a>.

For Java, it is recommended to look through the numerous demo programs in the [Java interface to DTWAIN repository](https://github.com/dynarithmic/twain_library-java).

----------

### Programming issues with an event driven system such as TWAIN.

Since TWAIN is an event-driven system, it is advantageous for whatever language you use to be able to support "callback" functions, i.e. functions that can be called during the TWAIN acquisition / scanning process.  There are a lot of events that occur during the acquisition process that you may want to take advantage of (for example, page about to be scanned, page scanned successfully, immediate access to the acquired image, etc.), and having the ability to capture these events will give your application the most flexibility.  

For example, please see the DTWDEMO.exe example program when acquiring to a PDF file, as a page number is added to the page for each page that is acquired by the device.  This is only possible (using DTWAIN) by using callbacks.
  
The **DTWAIN_SetCallback** and **DTWAIN_SetCallback64** sets up your callback function to intercept these events and act accordingly.  

Here is an example C++ program that puts a page number on the acquired image files, saved as a PDF document.  

    #include "dtwain.h"
    #include <iostream>
    #include <cstring>

    DTWAIN_SOURCE current_source;

    // Demonstrate callback mechanism 
    LRESULT CALLBACK TwainCallbackProc(WPARAM wParam, LPARAM lParam, LONG_PTR UserData)
    {
       // Page count  
       static int pdf_page_count = 1;

       // detect if the notification is due to the page about to be saved
       if ( wParam == DTWAIN_TN_FILEPAGESAVING )
       {
            // write text to the bottom left of the PDF page 
            char text[50]; // create the text string
            sprintf(text, "Page %d", pdf_page_count); 
            ++pdf_page_count;

            // add the text to the page 
            DTWAIN_AddPDFTextA(current_source, 
                               text,     // text to write on the page 
                               100, 100, // (x, y) postion 
                              "Helvetica", // font to use 
                               14, // font height, in PDF points
                               DTWAIN_MakeRGB(255, 0, 0), // Red text 
                               0, 100.0, 0, 0.0, 0, // scaling, lead, etc. 
                               DTWAIN_PDFTEXT_CURRENTPAGE); // flags denoting when to write this text
       }
       return 1;
    }
    
    int main()
    {
        // initialize and acquire image and save to BMP file 
        if ( !DTWAIN_SysInitialize() )
           return 0;  // TWAIN could not be initialized 

        current_source = DTWAIN_SelectSource();
        if ( current_source )
        {
            // Enable the callback notification/mechanism 
            DTWAIN_EnableMsgNotify(TRUE);
            DTWAIN_SetCallback(TwainCallbackProc, 0);

            // Acquire to a multipage PDF file 
            DTWAIN_AcquireFileA(current_source, "test.pdf", DTWAIN_PDFMULTI, DTWAIN_USENATIVE | DTWAIN_USENAME,
                                DTWAIN_PT_DEFAULT, DTWAIN_MAXACQUIRE, TRUE, TRUE, NULL);
        } 
        DTWAIN_SysDestroy();         
    }         


Languages such as C, C++, C#, can use callbacks (sometimes referred to as *delegates* in the .NET world) to allow such functionality.  Other languages also have the capability to set callbacks.  Please refer to the documentation for the language you use to see if callback functionality exists (if you can get the **DTWAIN_SetCallback** or **DTWAIN_SetCallback64** to work for you, then you're not going to have any issues).

----------


### I am ambitious and would like to build the libraries, debug the internals, etc.  How do I get started? ###

The source code and instructions for building DTWAIN are found [here](https://github.com/dynarithmic/twain_library_source/tree/main). 

----------


### Is DTWAIN compatible with Linux? ###
Currently, there is no official support for Linux, but things are changing rapidly.

As some may be aware, the TWAIN standard itself is implemented for Linux, but my opinion is that the support is poor.  There is little in terms of actual TWAIN sources to run tests against, and only certain Linux distributions are "supported" (I put this in quotes, since it is still difficult to find TWAIN drivers to run tests against).

The Linux distribution must have the Data Source Manager (DSM) installed (**usr/local/lib/libtwaindsm.so**) before proceeding.  The current distributions that we are aware of that have a working TWAIN Data Source Manager (DSM) is Ubuntu.  We were able to rebuild the DSM (**/usr/local/lib/libtwaindsm.so**) for Fedora 29 (but Fedora is not officially supported, according to the build scripts available for the building of the DSM).  

Since there are no pre-built DSM binaries, you can find the DSM source code [here on Github](https://github.com/twain/twain-dsm) and attempt to build the binaries yourself.  However, you may need to change the build scripts, since some of them are hard-coded for certain Ubuntu versions.

Once the DSM is built and installed, the build of DTWAIN can be done using the files in the source directory.  We used the CodeBlocks IDE (using g++ 6.x or higher) to organize the project (we don't currently have a CMake for DTWAIN, but one is in the works).  We also used a custom FreeImage script to do the FreeImage build.  Once done, we found no issues communicating with the Linux DSM with a small test program:

    #include "dtwain.h"
    int main()
    {
        DTWAIN_SysInitialize();     /* basic setup */
        DTWAIN_StartTwainSession(); /* communicate with libtwaindsm.so */
        DTWAIN_SysDestroy();         
    }         
  
This is more or less a proof-of-concept.  We will keep you posted on any further progress.

----------
### Is there a .NET wrapper for DTWAIN? ###

We have language bindings (pinvoke's) for C# and Visual Basic.  However we currently lack a true .NET component (just did not have the time to create one).  If anyone out there is willing to create such a .NET component, we are willing to add the component to this repository once vetted and well-tested (and of course, give full credit to the author(s)).

----------
### Is there a C++ class wrapper for DTWAIN? ###

If you're a C++ programmer, and want a wrapper around the DTWAIN libarary, we do have a C++ wrapper for DTWAIN located in the <a href="https://github.com/dynarithmic/twain_library/tree/master/demos/C_C%2B%2B/cpp_wrapper_lib" target="_blank">demos\cpp_wrapper_lib</a> directory.  For more information, see the <a href="https://github.com/dynarithmic/twain_library/blob/master/demos/README.md" target="_blank">README.md</a> in the demos directory.

----------

### Acknowledgments ###

* Other than the interface to the TWAIN libraries to allow image acquisition, The Dynarithmic TWAIN Library makes use of the following third-party libraries to process image data.

  * FreeImage  - [Open source Imaging library](http://freeimage.sourceforge.net/).  Note:  We use the FreeImage Public License terms [found here](https://github.com/dynarithmic/twain_library/tree/master/source/FreeImage/license-fi.txt).
  * SimpleINI  - Open source (MIT License) [INI file parsing library](https://github.com/brofield/simpleini)
  * nlohmann/JSON library - [Open source C++ JSON library](https://github.com/nlohmann/json)
  
* In addition, an interface to the [TOCR OCR library](http://www.transym.com/).  This allows image files to be translated to text files for functions such as DTWAIN_AcquireFile with the type to acquire being DTWAIN_TXT.  To use TOCR requires you to purchase a separate license from Transym (we do not provide the DLL or the libraries, just the function calls to allow usage of the TOCR library).
  
* All other raw image processing, plus the interface to the TWAIN system itself, is done without third-party libraries or third-party source code.  

----------

### Final note for developers

We expect DTWAIN to work flawlessly with almost every TWAIN-enabled device.  However, there can be issues that may happen with devices that either do not behave properly, or exercise DTWAIN in a way that's unexpected (for example, we came across a SamSung TWAIN driver for their phone that didn't follow TWAIN compliance, and thus caused issue with DTWAIN).  

Given this, the secondary goal of making DTWAIN open source is for you to contribute your fixes to the current DTWAIN code if you come across a device that doesn't work properly with DTWAIN.  There are literally thousands of TWAIN enabled devices out there, old and new, some manufacturers may have discontinued the device model, or maybe even the device manufacturer has gone out-of-business.  

Thus, the nature of "fixing" DTWAIN to work with a device that has issues is not possible to be done from a distance without having the device on-hand.  Since there are thousands of devices out there, and more than just a few have TWAIN compliance issues, we rely on our contributors who have the faulty TWAIN device ready and on-hand to debug the issue.  

You can download the source code [here](https://github.com/dynarithmic/twain_library_source/tree/main), follow the directions, and thus debug a very simple program that utilizes the device you have in-house.  Note that you should be familiar with C++, as the base library is written in this language.


----------

### Who do I talk to if I have further questions?  What if I have issues with the DTWAIN Library?

All questions concerning usage, possible bugs, etc. of the Dynarithmic TWAIN Library must have an issue created on the [Issue page](https://github.com/dynarithmic/twain_library/issues) so as to allow further investigation.

Note that issues will **not** be addressed at **dynarithmic.com** (website or email domain), and instead all issues must be directed to the Github issues page noted above.

--------

### Who authored the Dynarithmic TWAIN Library?

The Dynarithmic TWAIN Library's principal developer is Paul McKenzie, and can be reached at [paulm@dynarithmic.com](mailto::paulm@dynarithmic.com).  

In addition to 30+ years in the industry, I have made extensive contributions to the [CodeGuru](http://www.codeguru.com) C++ and Visual C++ forums, being one of the top contributors for over 15 years starting in 1999, and since 2014, moved on to  [StackOverflow](https://stackoverflow.com/users/3133316/paulmckenzie?tab=profile), where hopefully I am making an impact with other passionate programmers.  Also, I have had the distinction of being a Microsoft MVP for 10 years running in the Visual C++ category.
