DTWAIN Version changes

5.8.2

- [Possible breaking change if you are acquiring in duplex mode]

  Clarified the usage of the "number of pages" argument to the DTWAIN_Acquire...()
  functions when the device is acquiring in duplex mode.  If the device is in 
  duplex mode, the number of pages will specify the number of sheets of paper to
  process (front and back side), and not the number of total images.

  For example:
  DTWAIN_EnableDuplex(Source, TRUE);  // Enable the duplex unit
  //...
  DTWAIN_AcquireFile(Source, "filename", DTWAIN_BMP, DTWAIN_USENATIVE, DTWAIN_PT_DEFAULT,
                     2, // This is the number of pages argument
                     1, 1, NULL);

  This will acquire 2 sheets (front and back), making a total of 4 images. 

  Note that if your current code doubled the "number of pages" count due to inconsistencies with 
  the page count setting, and you upgrade to 5.8.2, you may have to remove the doubling of the 
  page count, and rebuild / retest the application to ensure that the page count is correct 
  when the device is in duplex mode.                    
                        
- Add a [SheetCount] section to dtwain32.ini and dtwain64.ini.  This section is for
  devices that support the CAP_SHEETCOUNT capability, but do not implement this 
  capability correctly when acquiring in duplex mode.  For example:

  [SheetCount]
  MyScannerName=IMAGES

  will assume that the device named "MyScannerName", if CAP_SHEETCOUNT is supported,
  will actually require DTWAIN to double the page count specified when a 
  DTWAIN_Acquire...() function is called.

- The DTWAIN_GetCapValuesEx...(), DTWAIN_SetCapValuesEx...(), DTWAIN_ArrayGetCapValuesEx...()
  and DTWAIN_ArraySetCapValuesEx...() functions will now accept the TWAIN container constant 
  names in addition to the DTWAIN container names when specifying the container to use.

  Previously, these functions only accepted the DTWAIN container names, for example,
  DTWAIN_CONTONEVALUE instead of TWON_ONEVALUE.  Now these functions will accept the 
  DTWAIN container constant name or the TWAIN container constant name.

- Added function DTWAIN_EnableGetMessageLoopDetection() that will turn on or off
  the auto-detection by DTWAIN to determine if the user-environment will successfully
  acquire images using the Windows API GetMessage() instead of the default PeekMessage().  

  By default, the auto detection is on, with the fallback being to use PeekMessage().
  However, it has been discovered that the auto-detection should always be turned off for 
  environments such as the Java Virtual Machine (JVM).

- The DTWDEMO32 and DTWDEMO64 demo programs now contains a method of setting most capability 
  values before acquiring images.  This allows testing of the device's capabilities during
  the acquisition (for example, auto-deskew, auto-rotate, possibly custom caps, etc.).  
  The capabilities must be able to be fully negotiated in state 4 (TWAIN Source is open), and not need
  to be negotiated during states 5, 6, or 7 (this is when the TWAIN Source is showing the user-interface
  and/or in the process of acquiring images).  

  This new option is available through the main menu once a TWAIN Source has been selected:

  "Source Selection Test -> Source Properties.." 

  and the lower left "Capability Info" box will contain a check box item "Reset Caps On Exit".  
  If you have set capability values through the "Test Capability" functionality, you must uncheck 
  the "Reset Caps On Exit" check box, so as to maintain the newly set capability values when the 
  Source Properties dialog is closed.

- Added sending DTWAIN_TN_ACQUIREPAGESTOPPING and DTWAIN_TN_ACQUIREPAGESTOPPED notifications
  to the application after the application returns 0 from the DTWAIN_TN_QUERYACQUIREPAGES 
  notification.  

  The DTWAIN_TN_ACQUIREPAGESTOPPING is sent immediately after receiving a 0
  from the application on the DTWAIN_TN_QUERYACQUIREPAGES notification.

  The DTWAIN_TN_ACQUIREPAGESSTOPPED is sent once the acquisition has stopped (the Source
  has either returned to the Source user-interface, or if no user-interface is used,
  is returning back to the application).

- Added sending DTWAIN_TN_QUERYUPDATEDIBORIG and DTWAIN_TN_QUERYUPDATEDIBRESAMPLED
  notifications after the image is retrieved from the TWAIN device (DTWAIN_TN_QUERYUPDATEDIBORIG)
  and after the image has been potentially modified by DTWAIN (DTWAIN_TN_QUERYUPDATEDIBRESAMPLED).
  
  These notifications are used for: 

      a) DTWAIN_AcquireNative(Ex), 
      b) DTWAIN_AcquireBuffered(Ex) using no compression and no user-defined buffer,
      c) DTWAIN_AcquireFile(Ex) with the DTWAIN_USESOURCEMODE flag not set.

  These notifications give the application the option of adjusting the current acquired image.  
  To do this the application should call DTWAIN_GetCurrentAcquiredImage() to get the DIB 
  (Device Independent Bitmap) handle,  and replace the current acquired image by calling 
  DTWAIN_UpdateCurrentAcquiredImage() with the new DIB.  Note that the bitmaps must be in 
  DIB format, as this is the image type that the device will use.

  The return value for these notifications should be 1, since DTWAIN on return will only check if the
  DIB has been updated, and not specifically the return value.

  The DTWAIN_SetUpdateDibProc function that sets up a function that allows changing the DIB will
  still exist, but it is highly recommended to use the new notifications, as they allow 
  changing the DIB both when the image is retrieved directly from the device, and after the 
  image has been resampled.

- Reordered ordinal numbers used in the DTWAIN DLL to have consecutive numbering.  The reordering
  of the ordinal numbers reduces the size of the DTWAIN DLL.

  This should affect a very small number of users who are using a programming environment that
  relies on explicit usage of the DLL's internal ordinal numbers to identify the 
  exported DLL functions.  If you are one of the few programmers using the ordinal numbers within
  the DTWAIN DLL, you will have to change your application to use the new ordinal numbers.
  
- Added DTWAIN_RotateImage function that rotates a Device Independent Bitmap by n degrees:  

  HANDLE DWAIN_RotateImage(HANDLE originalDib, DTWAIN_FLOAT degrees);
 
  The return value will be a copy of the original DIB, but with the image rotated.  The original
  DIB is not modified.  This function can be used for the notifications mentioned above 
  (DTWAIN_TN_QUERYUPDATEDIBORIG and  DTWAIN_TN_QUERYUPDATEDIBRESAMPLED).

- Added DTWAIN_NODELETEDIBS file flag to DTWAIN_AcquireFile and DTWAIN_AcquireFileEx.
  This file flag will allow all of the generated Device Independent Bitmaps to be retained
  in memory instead of automatically being deleted when the image file is saved.  

  To retrieve the bitmaps, the function DTWAIN_GetAcquisitionArray() should be used after 
  calling DTWAIN_AcquireFile(Ex).  The return value is a DTWAIN_ARRAY of the acquisitions,
  similar to the DTWAIN_ARRAY that is returned for DTWAIN_AcquireNativeEx().  

  Example:
     DTWAIN_SOURCE Source;
     DTWAIN_AcquireFile(Source, "filename", DTWAIN_BMP, 
                        DTWAIN_USENATIVE | DTWAIN_NODELETEDIBS, // Do not delete the DIBS
                        ... other parameters
                       );

     DTWAIN_ARRAY dibs = DTWAIN_GetAcquisitionArray(Source);
     // Get the first dib from the first acquisition attempted
     HANDLE oneDib = DTWAIN_GetAcquiredImage(dibs, 0, 0);  
     //...
     // Destroy the acquisition array
     DTWAIN_DestroyAcquisitionArray(dibs, TRUE);

- Fixed possible NULL being returned when calling DTWAIN_ArrayCreateFromCap() on a 
  custom capability.

- Fixed potential memory access violation when discarding images during buffered transfers.
  This can occur if the DTWAIN_TN_QUERYPAGEDISCARD user notification returns 0.

- Fixed potential memory leak when removing images after DTWAIN_AcquireFile(Ex) is called.

- Fixed potential memory access violation where DTWAIN_GetCapValuesEx() and 
  DTWAIN_GetCapValuesEx2() will return success when given a data type that is not 
  compatible with the actual data type used by the TWAIN driver.  

  This is a rare case where the driver returns a success code, but the actual results 
  should be a failure in setting the capability due to the driver not returning any 
  cap values.  This can occur if the client program calls either of the 
  DTWAIN_GetCapValuesEx... functions using the wrong data type.

- Fixed wrong error code being returned if a DTWAIN function that requires the DTWAIN
  DLL to be initialized is called.


5.8.1

- Added SVG and SVGZ file formats to DTWAIN_AcquireFile() and DTWAIN_AcquireFileEx().
  The constants are DTWAIN_SVG and DTWAIN_SVGZ for SVG and SVGZ types, respectively.
  
  The SVG that is produced will be vectorized for black=and-white, 1 bit-per-pixel
  images, and for bit depths greater than 1, the SVG will consist of embedded base-64 
  encoded PNG data.

- Added DTWAIN_TN_QUERYACQUIREPAGES notification to allow an application to stop acquiring
  pages during the acquisition process.  Returning a value of 0 from this notification 
  will stop the acquisition of pages. 

  Note that returning 0 does not guarantee that the physical device (if using a 
  document feeder) will stop feeding pages.  Instead, the subsequent pages being fed 
  will not be processed by DTWAIN (for example, no bitmaps created, no further pages added 
  to multipage image files, etc.), and will return the acquisition process back to either
  showing the user-interface (if the user-interface was shown), or back to the caller of
  the DTWAIN_Acquire...() function if no user-interface was shown.

- Add DTWAIN_EnableBarcodeDetection() function that will enable or disable the 
  bar code detection for the TWAIN driver.  Internally, this is basically a wrapper for 
  DTWAIN_SetCapValues() using the ICAP_BARCODEDETECTIONENABLED capability and the 
  MSG_SET set type.  Note that the TWAIN driver must already support bar code detection
  for this function to have any effect.

- Eliminate extraneous TWAIN messages from log files if DTWAIN_LOG_ISTWAINMSG option 
  is turned off.  This change reduces the size of log files by a very large margin.

- Determine at runtime if the client application requires GetMessage() processing instead
  of PeekMessage() processing when acquiring images.  Some script and automation 
  applications (for example, Macro Scheduler and others) may require GetMessage() 
  processing, since the internal architecture of these applications require a blocking 
  message queue, which GetMessage() provides. 

- Send DTWAIN_TN_SOURCEDETAILS notifications to the application when DTWAIN_GetSessionDetails()
  or DTWAIN_GetSourceDetails() is called.  The LPARAM of the notification will be a pointer to
  a null terminated ASCII string that represents the Product Name of the Source that is being processed.

- Fix various issues with DTWAIN_SetCapValues() using the MSG_SETCONSTRAINT set type.

- Address potential exception thrown when calling DTWAIN_GetSourceDetails() or
  DTWAIN_GetSessionDetails().  

- Fixed DTWAIN_GetBitDepth() to ensure that the returned DTWAIN_ARRAY is not 
  destroyed.

- Changed function signature of DTWAIN_EnumSupportedCapsEx().  The function will now return
  a DTWAIN_ARRAY that consists of all of the device's capabilities.  If your application called 
  this API functions, you will have to rebuild your application to comply with the new 
  function signature.



5.8.0

- Improved TWAIN Driver Compatibility

  The default TWAIN message loop has been changed from a blocking 
  GetMessage() loop to a non-blocking PeekMessage()-based loop while 
  a source is acquiring images.

  While the TWAIN specification uses GetMessage(), recent experience 
  has shown that some TWAIN drivers assume continuous, non-blocking 
  message processing and may stall when the application thread blocks. 
  This behavior is most commonly observed during source UI behavior,  
  such as non-responsive user-interfaces, long transfers, or cancellation.  

  The new default avoids blocking the message loop, allowing idle-time 
  processing and re-entrant messaging required by certain drivers. This change 
  improves stability and compatibility, particularly with legacy, OEM-rebranded, 
  and network-based sources.

  For applications that require a blocking loop, the previous GetMessage 
  behavior is still supported and can be explicitly enabled using the
  DTWAIN_EnablePeekMessageLoop() API function and specifying FALSE (or 0) as the
  parameter, or creating an entry in the DTWAIN32.INI or DTWAIN64.INI file 
  under the [TwainLoopGetMsg] section.

- Add ability to rotate and skew text that is added to a PDF page.  
  See the new DTWAIN_PDFTEXTELEMENT type and the supporting API functions.

- Add DTWAIN_DLG_CENTER_CURRENT_MONITOR flag to DTWAIN_SelectSource2() function.
  This flag allows the "Select Source" dialog to be centered with respect to the 
  current monitor.

- Fixed the DTWAIN_DLG_CENTER logic in DTWAIN_SelectSource2() to properly center 
  the "Select Source" dialog box with respect to the parent window if the parent 
  window is moved to another monitor.

- Fixed potential memory leak when using functions that takes a pointer
  to a DTWAIN_ARRAY.

- Fixed potential illegal memory access if DTWAIN_SetCapValues() is given an 
  invalid DTWAIN_ARRAY of values.

- Ensure that calling DTWAIN_CloseSource() while the Source is acquiring images
  will not close the source.  Instead, a return value of FALSE will be
  given, and the last error code is set to DTWAIN_ERR_SOURCE_ACQUIRING.

- The DTWDEMO32 and DTWDEMO64 demo programs now contains full capability testing.  This
  is available through the main menu once a TWAIN Source has been selected:

  Source Selection Test -> Source Properties.. 

  and the lower left "Capability Info" box will contain "Test Capability".  
  This will have full testing for setting and getting a capability's values.

- The C# and Visual Basic .NET full demo projects have been updated to include 
  features that exist in the DTWDEMO32/64 program.  This includes the testing of
  any TWAIN capability using MSG_GET, MSG_GETCURRENT, MSG_GETDEFAULT, etc.
  options.

- C#, Visual Basic, and F# language bindings have been rewritten to use
  the .NET string marshalling logic instead of providing separate "A" and
  "W" functions for ANSI and wide-string functions.  

  Basically this means that existing C#, VB or F# code that calls a 
  DTWAIN function that uses the language bindings provided will not build
  if an "A" or "W" function is called.  Instead, the program should
  call the general function, and the .NET string marshalling logic will 
  direct the call to the proper function.  For example, if your program
  currently calls DTWAIN_GetSourceProductNameA or DTWAIN_GetSourceProductNameW,
  you must instead call DTWAIN_GetSourceProductName.
  


5.7.2

- Fixed potential issue with setting the CAP_CAPTION capability.

- Added the following programming language bindings:

    D    (dtwainapi.d)
    F#   (dtwainapi.fs).
    Go   (dtwainapi.go).
    Rust (dtwainapi.rs).

- Changed name of python binding to dtwainapi.py.

- Changed name of Ruby binding to dtwainapi.rb.

- Ruby language binding now includes a Ruby definition for the TWAIN TW_IDENTITY struct.

- Updated C# and Visual Basic language bindings to properly handle DTWAIN
  callback functions.

- Added C# and Visual Basic language bindings that allows the C# or VB application to "manually" 
  load the DTWAIN DLL at runtime (the names of the binding files are dtwain_dynamic.cs and 
  dtwain_dynamic.vb, respectively).

- Addressed issues with some language resources (Chinese, Greek, Japanese, etc.)
  not displaying strings correctly within the TWAIN "Select Source" dialog when 
  calling DTWAIN_SelectSource2() (this fix is only for the Unicode build of the DTWAIN DLL's,
  i.e. dtwain32u.dll, dtwain32ud.dll, dtwain64u.dll, and dtwain64ud.dll)

- Changed undocumented API function name from DTWAIN_GetSavedFilesCount to 
  DTWAIN_GetFileSavePageCount.  This is a breaking change if your application used this
  function.  In a future version of DTWAIN, this function will be fully documented.


5.7.1

- Change name of Ruby binding to dtwain.rb from dynarithmic.rb

- Added Lua language binding (binding uses LuaJit)

- Upgraded following internal image libraries:

      libtiff  --> 4.7.1
      libpng   --> 1.6.50
      libopenjpeg --> 2.5.4
      libwebp  --> 1.6.0

- Added the DTWAIN_SetFeederWaitTime() API function.  This function allows devices with document feeders that
  can detect whether paper is placed within the feeder to wait for a specified number of seconds before
  automatically starting the acquisition process.  DTWAIN_SetFeederWaitTime() only works if the 
  device's user-interface is not shown during the acquisition process.  If the user-interface is shown
  DTWAIN_SetFeederWaitTime() has no effect.

  The prototype is as follows:

  DTWAIN_BOOL DTWAIN_SetFeederWaitTime(DTWAIN_SOURCE Source, LONG WaitTime, LONG WaitFlags)

  where 

  Source is the TWAIN Source

  WaitTime is the maximum number of seconds to wait before the acquisition starts or terminates with 
  no paper in the feeder.

  WaitFlags is either DTWAIN_FEEDER_TERMINATE or DTWAIN_FEEDER_USEFLATBED.

  If WaitTime is 0, then no wait time is applied, and the acquisition starts immediately, whether or not
  there is paper in the feeder.  If WaitTime is DTWAIN_WAIT_INFINITE, then the wait time is infinite 
  until paper is placed in the device.  Any other value for WaitTime will allow the feeder to wait for 
  the number of seconds.

  If the number of seconds have elapsed without paper placed in the feeder, the WaitFlags determines 
  what happens on the elapsed time.  

  If WaitFlags is DTWAIN_FEEDER_TERMINATE, the acquisition terminates with a DTWAIN_TN_FEEDERTIMEOUT 
  notification sent back to the application.  If WaitFlags is DTWAIN_FEEDER_USEFLATBED, the acquisition
  continues, but will use the flatbed portion of the device if the device has an available flatbed.

  Example:
  DTWAIN_SOURCE Source;
  DTWAIN_SetFeederWaitTime(Source, 30, DTWAIN_FEEDER_TERMINATE);
  DTWAIN_AcquireNative(Source,...);

  When DTWAIN_AcquireNative() is called, if the device has a feeder that can detect paper, a maximum of
  30 seconds will elapse before the acquisition is terminated.  If before 30 seconds has elapsed, paper
  is placed in the feeder, the acquisition will immediately start.

- Added DTWAIN_GetExtImageInfoDataEx() function.  This function performs the same as the
  DTWAIN_GetExtImageInfoData() function, with the only difference being that DTWAIN_GetExtImageInfoDataEx()
  function returns the DTWAIN_ARRAY instead of the client providing the address of a DTWAIN_ARRAY.

- Added DTWAIN_DLG_SAVELASTSCREENPOS flag to DTWAIN_SelectSource2() that will allow the "Select Source"
  dialog box to be positioned at the previous position when a prior call to DTWAIN_SelectSource2() was
  called.  

  This allows the user to position the Select Source dialog, close the dialog, and if the dialog box
  is opened again using DTWAIN_SelectSource2(), the dialog box is positioned at the previous location on
  the screen.

- Added notification code DTWAIN_TN_PREACQUIRESTART notification.  This is always sent prior to the 
  device acquiring the first image of the first acquisition attempted, i.e., any call to the 
  DTWAIN_Acquire... family of functions will send this notification.  If the application processes
  this notification, a return value of 1 from this notification will start the acquisitions, a return
  value of 0 will stop the acquisitions.

 

5.7.0

- Added support for generating JPEG-XR files when using DTWAIN_AcquireFile() and DTWAIN_AcquireFileEx().
  The DTWAIN file constant to use is DTWAIN_JPEGXR.  In addition, the DTWAIN_SetJpegXRValues() can be 
  used to set the quality factor and whether a progressive JPEG-XR file will be generated.  By default.
  the quality factor is 80 (the scale goes from 1 to 100, where 100 is lossless compression), and
  the default file is not a progressive JPEG-XR file.

- Updated twaininfo.txt file to support DTWAIN_JPEGXR settings.  You must use the updated twaininfo.txt
  file with DTWAIN version 5.7.0.

- Changed signature of DTWAIN_SetPDFAESEncryption() function introduced in version 5.6.9 to allow 
  AES 128-bit and the newly introduced AES 256-bit encryption to be used when creating encrypted PDF
  files (see below).  To enable 128-bit encryption, the second argument to DTWAIN_SetPDFAESEncryption()
  must be DTWAIN_PDF_AES128, and the third argument as TRUE.

- Added AES-256 bit encryption option when creating encrypted PDF files.  To enable this option, the
  DTWAIN_SetPDFAESEncryption() function must be called with the second argument as DTWAIN_PDF_AES256.
  and the third argument as TRUE.  Note that you will still need to call DTWAIN_SetPDFEncryption() to 
  set up the initial encryption options (user/owner password, permissions, etc.)

- Fixed possible issue with creating valid PDF files that contain PDF streams with embedded left 
  or right parentheses characters.  

- Ensure C# language binding compile without warnings for C# version 8.0 and above.

- Added DTWAIN_ARRAY functions:

     DTWAIN_ArrayFloatToANSIString 
     DTWAIN_ArrayFloatToWideString
     DTWAIN_ArrayANSIStringToFloat
     DTWAIN_ArayWideStringToFloat
     DTWAIN_ArrayFloatToString
     DTWAIN_ArrayStringToFloat

   The functions above allow conversions from DTWAIN_ARRAY's that consist of floats to string types and
   vice-versa.  This allows languages that have difficulty with C/C++ double types (for example, XBase++)
   to call functions that return DTWAIN_ARRAYs of floating point values, and also to call DTWAIN functions
   that require floating point arrays.

   Example pseudo-code:
      DTWAIN_ARRAY a = DTWAIN_ArrayGetCapValues(Source, ICAP_XRESOLUTION, DTWAIN_CAPGET);
      // convert to string, since our language can't handle float variables
      DTWAIN_ARRAY converted = DTWAIN_ArrayFloatToANSIString(a);
      // Now converted has the string versions of the floating point values.

   Note that to prevent memory leaks in the above code, both "converted" and "a" need to be eventually destroyed 
   using DTWAIN_ArrayDestroy, since a copy of the DTWAIN_ARRAY a has the converted values.


5.6.8

- Replaced crypto++ with Portable C++ Hashing Library by Stephan Brumme, resulting in 
  smaller binaries.

- Added DTWAIN_PDF_ALLOWALL option to DTWAIN_SetPDFEncryption() set of encryption permissions. 
  This allows easier manipulation if you want to allow all operations on an encrypted PDF
  except for a few options, simply by subtracting the option(s) you want to disable 
  from DTWAIN_PDF_ALLOWALL.  For example: 
 
  DTWAIN_SetPDFEncryption(Source, TRUE, "Owner", "User", DTWAIN_PDF_ALLOWALL - DTWAIN_PDF_ALLOWCOPY, TRUE);

  will allow all operations on the encrypted PDF except for copying (copying will be disabled).

- Added AES-128 bit encryption option when creating encrypted PDF files.  To enable this option, the
  DTWAIN_SetPDFAESEncryption() function must be called with the second argument as TRUE.  
  Note that you will still need to call DTWAIN_SetPDFEncryption() to set up the initial encryption 
  options (user/owner password, permissions, etc.)

- Added the following functions that return DTWAIN_ARRAYs, rather than the user having to supply a pointer
  to the DTWAIN_ARRAY as a parameter.  A table of the new functions and the equivalent functions is as follows

  New function                              Equivalent function
  ------------                              ------------------- 
  DTWAIN_EnumBottomCamerasEx                DTWAIN_EnumBottomCameras 
  DTWAIN_EnumCamerasEx2                     DTWAIN_EnumCameras 
  DTWAIN_EnumCamerasEx3                     DTWAIN_EnumCamerasEx 
  DTWAIN_EnumExtImageInfoTypesEx            DTWAIN_EnumExtImageInfoTypes 
  DTWAIN_EnumPixelTypesEx                   DTWAIN_EnumPixelTypes 
  DTWAIN_EnumSupportedExtImageInfoEx        DTWAIN_EnumSupportedExtImageInfo 
  DTWAIN_EnumTopCamerasEx                   DTWAIN_EnumTopCameras 
  DTWAIN_RangeExpandEx                      DTWAIN_RangeExpand 

- [New]: Added Ruby language binding.  

- The DTWAIN demo program is now DTWDEMO32.exe and DTWDEMO64.exe instead of DTWDEMO32U.exe and 
  DTWDEMO64U.exe, respectively.

- Fixed Delphi demo program when run using 64-bit DTWAIN.

- Updated C#, Visual Basic, and Delphi language bindings.  You should use these new language bindings
  with version 5.6.8 of the DTWAIN DLL's.  

  In addition, some of the C# and Visual Basic function definitions have changes with respect to strings and 
  null value parameters.  If you get a compilation error in your existing C# or Visual Basic code using the 
  updated language bindings, more than likely the error will point to the improper usage of specifying
  a null parameter value.  Please adjust your code accordingly (for example, for Visual Basic, this 
  may mean using "Nothing" as the argument instead of IntPtr.Zero).  

  The VB and C# demos have been updated so you can view the demo source code if you are unsure how to pass 
  the NULL values to the DTWAIN functions that have NULL parameters.


5.6.7

- Corrected various constants in the TWAIN constant lookup table.  

- Updated the DTWDEMO32/64 program to allow testing of the capabilities of the device ("Get" testing only).
  The "Source Properties" dialog now will have a "Test" button in the lower left list box where the 
  capability listing is located.  Selecting a capability and selecting "Test" will display an additional
  dialog with container and data type testing for the selected capability.

- For Python developers: Fixed python language binding for DTWAIN functions that requires parameters to be floating point, 
  in addition to defining the return type and argument types for all DTWAIN functions using ctypes.  

  Note that using this updated version of the python language binding may require you to  change some calls you are 
  making now to DTWAIN functions that require pointers or strings.  This is due to having the DTWAIN functions prototypes, 
  thus there is now stricter checking of types being sent to the DTWAIN functions.

- Breaking changes to the DTWAIN_FRAME related functions:

      1) Removed the following DTWAIN_FRAME related functions:
         DTWAIN_ArrayFrameGetAt
         DTWAIN_ArrayFrameSetAt

      2) Changed the signature of the following DTWAIN_FRAME related functions:
         DTWAIN_ArrayGetAtFrame now takes pointers to left, top, right, and bottom components.
         DTWAIN_ArraySetAtFrame now takes left, top, right, and bottom components. 

Note that the changes above may require a rebuild of your application if you utilize the mentioned 
DTWAIN_FRAME related functions.

- Updated the C++ wrapper class, C#, Visual Basic, Delphi, and python language bindings.  You 
  must use these new bindings so that they are in synch with the updated DTWAIN_FRAME functions.

- Added DTWAIN_ArraySetAtFloatString(), DTWAIN_ArrayGetAtFloatString(), DTWAIN_ArrayInsertAtFloatString(), 
  DTWAIN_ArrayInsertAtFloatStringN() and DTWAIN_ArrayFindFloatString() that allow string values to be used 
  when setting and retrieving floating point values within a DTWAIN_ARRAY that stores floating point values.

- Add functions DTWAIN_ArrayGetCapValues, DTWAIN_ArrayGetCapValuesEx, and DTWAIN_ArrayGetCapValuesEx2 that 
  are equivalent to DTWAIN_GetCapValues, DTWAIN_GetCapValuesEx, and DTWAIN_GetCapValuesEx2 except that 
  the DTWAIN_ArrayGet...  functions will return the DTWAIN_ARRAY of values instead of the client having 
  to pass the address of a DTWAIN_ARRAY as the last parameter.  This allows getting the capability values 
  easier for languages that do not have the facility to pass the address of a pointer (address of an address).

- Fixed issue with DTWAIN_ArrayFindFloat() failing to find certain floating point values stored in a 
  DTWAIN_ARRAY.

- Updated Perl language binding to use DTWAIN 5.6.7 API functions and constants.


5.6.6

- Upgraded following internal image libraries:

    libpng   --> 1.6.48

- If DTWAIN_SysInitializeNoBlocking() is called and returns 0, an errorlog*.txt file is
  created in the directory where the text resources would be found.  The file will 
  describes the error if DTWAIN could not be initialized.

- Ensure that TWAIN sources are not re-enumerated if already enumerated by previous DTWAIN
  functions.

- Removed unnecessary calls to the TWAIN logger if logging is not enabled.

- Removed some extraneous carriage returns when logging information.

- TWAIN condition codes are now only queried when TWRC_FAILURE is returned from the
  TWAIN Data Source Manager.  This is a change that alters the behavior that is detailed 
  in the version 5.6.1 update.


5.6.5

- Fix issue with missing TWAIN log header information.

- Fix issue with truncated DTWAIN version information being saved in 
  generated image files.

- Small speed optimization for DTWAIN_IsCapSupported().

- Internal code refactoring and cleanup, resulting in smaller DLL files.


5.6.4

- Ensure that invalid TWAIN Data Source Manager DLL's that attempt to be loaded at runtime are 
  immediately unloaded from the application when determined that the invalid DSM cannot be 
  utilized by DTWAIN.

- Remove unused imaging code.  This results in the DTWAIN DLL's being reduced by at least 
  100K bytes in size.

- Allow DTWAIN_SetDSMSearchOrderEx() to be recognized before calling DTWAIN_SysInitialize().
  This will allow querying for the availability of the TWAIN DSM using DTWAIN_IsTwainAvailable(),
  using a user-defined search logic for the TWAIN DSM DLL files, all before calling 
  DTWAIN_SysInitialize().  Before version 5.6.4, DTWAIN_SysInitialize() must always be called before 
  calling DTWAIN_SetDSMSearchOrderEx().

- Fix issue with DTWAIN_IsAcquiring() and DTWAIN_IsSourceAcquiring() not returning the correct
  status of the TWAIN device when acquiring images.

- Fix issue with DTWDEMO demo program to not allow DTWDEMO  to close while images
  are being acquired by the device.


5.6.3

- Fix code to check for invalid DTWAIN_FRAMEs being passed to DTWAIN_Frame...() functions.

- Fix issue with DTWAIN_RangeGetNearestValue() when using floating point range values.

- Various NULL pointer checks for some DTWAIN API functions that allow pointer values to be
  passed.

- Add missing TWEI_BARCODETEXTLENGTH to the data returned by utilizing Extended Image Information.

- For DTWAIN_TN_QUERYPAGEDISCARD notification, an additional return value of 2 from this notification
  allows the current generated page from the TWAIN device to not be destroyed, but will also not 
  be stored internally by DTWAIN.  This allows applications to take complete control of the generated 
  page without DTWAIN intervening in the management of the page.  

  In contrast, a return value of 1 from DTWAIN_TN_QUERYPAGEDISCARD keeps both the page generated, 
  and DTWAIN's handling of the page.  A return value of 0 will always discard the page, including
  the bitmap data representing the page.


5.6.2

- Fix potential exception from occurring when attempting to close a TWAIN source that did not 
  open successfully.

- Update DTWDEMO program to show bar code information while transferring images.

- Fix issue with handling TW_FRAME values when issuing calls to DTWAIN_SetCapValues() and
  DTWAIN_GetCapValues() that use TW_FRAME.

- Update Delphi language binding to properly handle the BOOL data type when calling DTWAIN
  functions that receive and return BOOL values.
  
- Add DTWAIN_EnumSupportedExtImageInfo() function that returns a DTWAIN_ARRAY of the
  supported TWEI_* extended image info types that the TWAIN source supports.  

  Note that this function can be called even if the Source is not acquiring images, provided
  that the Source is TWAIN 2.1 compliant.  If the source is not at least TWAIN 2.1 compliant,
  DTWAIN_EnumSupportedExtImageInfo() can only report the TWEI_* types when acquiring images
  (State 7 or when the DTWAIN_TN_TRANSFERDONE notification is sent to the application).

- Low Level Changes: These changes should be only used by programmers who are utilizing the 
  DTWAIN_CallDSMProc() interface to call through to the Data Source Manager directly, and the call
  requires the application to allocate memory for the triplet call.

     - Change parameters to DTWAIN_AllocateMemory() and DTWAIN_AllocateMemoryEx() to unsigned integers.

     - Add DTWAIN_AllocateMemory64() to allow allocation of memory greater than 4 GB.


5.6.1

- Fixed issue with setting the ICAP_FRAMES capability when calling 
  DTWAIN_GetCapValues() and DTWAIN_SetCapValues().

- Fixed issue with capability setting using MSG_RESETALL operation.

- Ensure that the TWAIN condition code (TWCC_xxxx) is retrieved for every call
  to the TWAIN Data Source Manager.  This included successful calls to the
  TWAIN DSM as well as DTWAIN calls that fail.  



5.6.0

- Added versions of the DTWAIN DLL that requires an installation of the Visual C++
  Runtime on the target machine.  This further reduces the disk size of the DTWAIN DLL's.

  The application must run on a system that has the Visual C++ Redistributables 
  (versions 2015 and above) already installed.  Since many applications would have 
  already installed the VC++ redistributables, the reduction in size of the DTWAIN DLL's 
  may be advantageous for your application. 

  For more information on this, and receiving the VC++ redistributables (if you want to install these
  files yourself):

  https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#visual-studio-2015-2017-2019-and-2022


- Upgraded following internal image libraries:

      libpng   --> 1.6.44
      libwebp  --> 1.5.0
      libtiff  --> 4.7.0
      libopenjpeg --> 2.5.0
  
- Changed determination of whether a TWAIN source can sense paper by
  querying the CAP_PAPERDETECTABLE capability, and if not supported
  query the CAP_FEEDERENABLED capability (for TWAIN driver compliancy testing --
  see the update below).  

- Report TWAIN compliancy error if CAP_PAPERDETECTABLE is not supported,
  but CAP_FEEDERENABLED is supported (CAP_PAPERDETECTABLE must be supported
  for a source/driver that supports a document feeder to be TWAIN compliant).

- For the above issues with CAP_PAPERDETECABLE, allow overrides of whether a 
  source/driver supports a paper sensor by introducing a [PaperDetectionStatus] setting
  in dtwain32.ini and dtwain64.ini.  Currently, only the Avision 176U scanners are
  set for this override.  

- Optimize queries to the source for paper detection and feeder status.  Previously,
  the underlying calls to the TWAIN subsystem were always done after the first time 
  the device was queried for this information.  As of this version, the first results are
  now cached instead of having to go to the TWAIN subsystem on subsequent queries.

- For DTWAIN_AcquireFile(), when using the source file transfer mode, send 
  DTWAIN_TN_FILEPAGESAVEOK and DTWAIN_TN_FILESAVEOK notifications on successful
  file transfer.  Currently, these two notifications are only sent when using 
  the native or buffered transfer modes when acquiring to an image file).

- Add function DTWAIN_SetFileCompressionType() and DTWAIN_GetFileCompressionType() to 
  ensure that the compression type used by source file transfer mode is utilized.
  Currently, the compression type other than TWCP_NONE is not guaranteed to be
  used, even if the compression type is supported.  

  The DTWAIN_SetFileCompressionType() function should be called before DTWAIN_AcquireFile()
  or DTWAIN_AcquireFileEx() (with the DTWAIN_USESOURCEFLAG mode set for these calls) to
  ensure the compression type will be used for the file transfer.

- Fixed memory leak in DTWAIN_ARRAY internal handling.


5.5.5

- Create versions of DTWAIN DLL that contains full logging and minimal logging.  The minimal
  logging versions of DTWAIN results in smaller sizes for the DLL files.

- Update CAP_PRINTERSTRING to use (by default) TWON_ONEVALUE container on setting capability.

- Allow internal TWAIN message loop to loop indefinitely until the Source UI is closed.  A new
  DTWAIN32.INI and DTWAIN64.INI section ("TwainLoopPeek") will list the TWAIN Product
  Names that will use the new looping mechanism using the Windows API function PeekMessage().  
  By default, the looping method used will be the same as previous versions of DTWAIN 
  (using the Windows API function GetMessage()).  

- Related to the update of the TWAIN message loop, functions DTWAIN_EnablePeekMessageLoop() and
  DTWAIN_IsPeekMessageLoopEnabled() allows programmatic control of which type of TWAIN message
  loop will be executed with a given TWAIN Source.  By default, the message loop uses the 
  Windows API function GetMessage() instead of PeekMessage().

- Fix issue with determining if TWAIN source supports DAT_FILESYSTEM functionality.

- Ensure setting string capabilities uses ANSI strings.

- Change parameters to certain API functions from LONG to DWORD to delineate signed versus unsigned values.  
  The sizes of LONG and DWORD, the only difference is that DWORD is an unsigned 32-bit integer 
  while LONG is a signed 32-bit integer.

- Add Japanese, Traditional Chinese, and Greek text resources.

- All lines in the logs generated with DTWAIN_SetTwainLog() have timestamps (with the 
  by-product of this change being that all the log lines are properly indented).

- DTWDEMO32 and DTWDEMO64 programs now do not require VCRUNTIME140.DLL to be present.

- On return of DTWAIN functions that handle pointers as input, the values that the pointers
  will point to are now logged (only available with full logging versions of DTWAIN DLL). 

- Added missing constants to twaininfo.txt

- DTWAIN_SelectDefaultSource() will now only make a call to the TWAIN DSM if the DSM is version 2
  or greater (TWAINDSM.DLL).

- DTWAIN_GetSourceDetails() now correctly reports custom capabilities that are also extended capabilities.



5.5.4

- Addressed issue with multiple calls to DTWAIN_SysInitialize() and DTWAIN_SysDestroy() not loading
  the twaininfo.txt file.

- Fixed issue with TW_FRAME and Extended Image Information not being processed correctly for
  the TWEI_FRAME setting.

- Fixed several incorrect language bindings for C#, Visual Basic, and Delphi.  Also corrected
  a few incorrect function pointer definitions in dtwimpl.h (used when using DTWAIN in a 
  C/C++ program that does not utilize import libraries). 

- Added missing constants to twaininfo.txt


5.5.3

- Fixed several issues with retrieving extended image information (for example, barcode text, 
  imprinter text, etc.) from TWAIN Sources using the DTWAIN Extended Image Information retrieval 
  functions (DTWAIN_InitExtImageInfo, DTWAIN_GetExtImageInfoData, etc.).

- Fixed issue with DTWAIN_ArrayGet...() functions possibly returning the incorrect status
  code.

- TWAIN Select Source dialog and OCR Select Engine dialogs are now similar and have the same
  functionality.  This includes adding DTWAIN_SelectOCREngine2() function that is similar
  to the current DTWAIN_SelectSource2() function, which allows positioning, sorting of the names
  in the dialog, etc.

- More thorough checks are done to detect an invalid twaininfo.txt at startup.  

- Update C++, C#, and Visual Basic full demo programs to include on the main menu
  a "Language" option.  This option allows you to dynamically switch the language used
  (for example, French, German, etc.) while the demo is running.  The changes in the
  language will be seen in the TWAIN Select Source dialog, and in the logging text if
  logging is chosen.


5.5.2

- Add support for acquiring buffered images using tiled data (DTWAIN_SetBufferedTileMode()).  
  The device must support the ICAP_TILES capability for tiled data to be sent.

- Fixed issue with custom resource files being loaded into memory using DTWAIN_LoadCustomStringResources()

- Fixed issue DTWAIN_EnumCameras returning strings that were not properly encoded when using Unicode
  build of DTWAIN.

- Fixed issues with DTWAIN_AcquireFile(Ex) and handling of file transfers directly from the TWAIN Source
  (DTWAIN_USESOURCEMODE flag).

- Add DTWAIN_LOG_CONSOLEWITHHANDLER to list of available flags to DTWAIN_SetTwainLog().  This flag is only
  applicable when logging to the console.  This flag allows safe(r) shutdown of DTWAIN if the logging
  console is terminated by Ctrl-C, closing the console window by clicking the 'X', etc.

- Add some missing C# and VB interface functions.

- Ensure that when logging to the console, the console is using UTF-8 encoding.

- More thorough test for corruption of the twaininfo.txt resource file when DTWAIN_SysInitialize()
  is called.

- Update C/C++ full demo program (DTWDEMO32 and DTWDEMO64) to show the JSON description of the opened 
  TWAIN Source when displaying the source properties.  The C# and VB version of DTWDEMOxx has also 
  been updated to show this information (see the FullDemo projects for C# and VB).

- Remove some resource constants from the language resource files.  These constants have now been moved to 
  twaininfo.txt.

- Updated code to detect the running Windows OS version when starting a DTWAIN log.  The new code
  now detects the latest Windows 11 version(s).  The new code is courtesy of PJ Naughter.

- Add various language files (Romanian, Russian, Portuguese, Simplified Chinese).


5.5.1

- Load default English resources if twainresourcestrings_english.txt is not found, and
  additional language resources are not specified.

- Optimizations to internal functions.

- Fix DTWAIN_SetDefaultSource() for TWAIN 2.x data source managers (TWAINDSM.DLL).  Note that
  DTWAIN_SetDefaultSource() is not guaranteed to work for TWAIN 1.x data source managers (TWAIN_32.DLL).

- Fix issue with DTWAIN_SelectOCREngine() not working for Unicode builds of DTWAIN.

- Adjust DTWAIN OCR error constants to match OCR error messages.

  
5.5.0

- Add support for Big TIFF files when calling DTWAIN_AcquireFile() and DTWAIN_AcquireFileEx().  
  For more information, see the new file type constants (DTWAIN_BIGTIFFNONE, DTWAIN_BIGTIFFLZW, etc.)
  Big TIFF files are TIFF files that are allowed to be greater than 4 Gigabytes in size.

- Update twaininfo.txt to add the new Big TIFF file type information.

- Update the DTWDEMO.exe demo program, as well as the C# and Visual Basic full 
  demo programs to display the TWAIN Source's custom data when displaying the Source Properties dialog box.

- Optimize DTWAIN_AcquireFile() and DTWAIN_AcquireFileEx() when an unsupported file type is 
  specified.

- Optimize DTWAIN_IsTwainAvailable() when determining whether TWAIN is installed.  The
  optimization is for the case where DTWAIN_IsTwainAvailable() is called before 
  DTWAIN_SysInitialize().

- Add function DTWAIN_IsTwainAvailableEx() to return a pipe-delimited string denoting
  the full TWAIN paths of both TWAIN 1.x and TWAIN 2.x Data Source managers.

- Optimize DTWAIN_OpenSource() in these scenarios:
    a) if called more than once on a TWAIN Source
    b) When initially opening a TWAIN Source by not checking for the status of the feeder
    c) Capability processing has been minimized when calling DTWAIN_OpenSource().

- Optimize DTWAIN_GetCapValues() and DTWAIN_SetCapValues() if a capability is not supported
  by the TWAIN Source.

- Fixed an issue with DTWAIN_GetCapValuesEx2(), where the passed-in TWAIN data type was not
  being processed correctly for all scenarios.

- Fixed issue with DTWAIN_TN_UIOPENING not being sent during DTWAIN notification processing.

- Fixed issue with DTWAIN_EnumCameras() not returning all of the camera information (only top
  and bottom cameras were returned).  Please note that "camera" in this context does not mean
  "digital camera", but instead the mechanism that scans the image.  Only TWAIN devices that
  support an internal file system (DTWAIN_IsFileSystemSupported()) will have the ability to 
  enumerate camera types.

- Fixed minor issue with DTWAIN_EnumCameras() and logging, where unsupported TWAIN drivers that
  do not have an internal file system would log an exception instead of returning an error.

- Added DTWAIN_EnumCamerasEx() that allows the application to enumerate any of the (currently)
  9 specific camera types defined by TWAIN.  The camera types are described by the TWAIN
  constants:

      DTWAIN_FT_CAMERA         
      DTWAIN_FT_CAMERATOP      
      DTWAIN_FT_CAMERABOTTOM   
      DTWAIN_FT_CAMERAPREVIEW  
      DTWAIN_FT_DOMAIN         
      DTWAIN_FT_HOST           
      DTWAIN_FT_DIRECTORY      
      DTWAIN_FT_IMAGE          
      DTWAIN_FT_UNKNOWN        

- Ensure that DTWAIN_GetCapValues() and other internal functions that call DTWAIN_GetCapValues() 
  clears the returned user array of values if the TWAIN capability being tested is not supported 
  by the device.

- Adjust twaininfo.txt to properly reflect the new TWAIN 2.x capability information.  
  Note: This new version of twaininfo.txt must be used with the current DTWAIN 5.5.x. 
  The older version of twaininfo.txt can only be used with DTWAIN version 5.4.x or below. 

- Updated the various language bindings (C#, Delphi, Visual Basic, etc.) to reflect the new
  additions of the Big TIFF file type.

- Updated the C/C++ "No import library" method of using DTWAIN to reflect the new functions,
  plus added missing DTWAIN API functions to dtwainx2.h and dtwimpl.cpp(.c).

- Added the function DTWAIN_TestGetCap() that allows testing of a TWAIN Source's capability's
  MSG_GET functionality for all containers and data types.  This function basically calls
  DTWAIN_GetCapValues(), checking for successful retrieval of information from the TWAIN
  device for each container type and data type supported by TWAIN.  The DTWAIN_TestGetCap() 
  function can be useful to determine a custom capability's container and data type if this 
  information is not known by the programmer.

  The return value for DTWAIN_TestGetCap() is a DTWAIN_ARRAY, where the array consists of LONG (32-bit) values.  
  The upper 16 bits of each value in the array denotes the successful data type, and the lower 16 bits 
  denote the successful data type.  The container type can be DTWAIN_CONTONEVALUE, DTWAIN_CONTRANGE,
  DTWAIN_CONTENUMERATION, and DTWAIN_CONTRANGE, while the data type will be one of the types defined
  in twain.h, i.e. TWTY_BOOL, TWTY_FRAME, TWTY_UINT16, etc.

  Note:  Use DTWAIN_TestGetCap() with caution, as DTWAIN will attempt to test *every* container type and 
  data type combination for the passed-in capability value.

- Other minor bug fixes and enhancements.


5.4.8

- Add additional TWAIN constants to twaininfo.txt

- Output version of twaininfo.txt to logs generated by DTWAIN_SetTwainLog

- Increase the maximum size of the DTWAIN resource and error strings to 8192 bytes.

- Added DTWAIN_GetResourceString,  DTWAIN_GetResourceStringA, and DTWAIN_GetResourceStringW 
  API functions to allow access to the resource and error strings loaded by DTWAIN.

- Fix issue with exception possibly occurring when closing TWAIN Source window without acquiring images.


5.4.7

- Fixed issue with loading 32-bit TWAINDSM.DLL if only found on the system path.

- Fixed issue with some DTWAIN API calls not retaining error codes when DTWAIN_GetLastError() is invoked.

- Added additional resource strings to the twainresourcestrings_*  resource files.


5.4.6

- Increase width of the label field in the TWAIN "Select Source" dialog when using DTWAIN_SelectSource2()

- Fix typo in dtwain64u.cs file.


5.4.5

- Upgraded following internal image, compression, and cryptography libraries:

      libpng   --> 1.6.43
      libwebp  --> 1.4.0
      zlib     --> 1.3.1
      	
- Fixed issue with saving to files using the DTWAIN_USEPROMPT flag when calling DTWAIN_AcquireFile.

- Fixed issue with DTWAIN_AcquireFileEx when using the DTWAIN_CREATE_DIRECTORY file flag.

- Added generation of Targa Run Length Encoded files to DTWAIN_AcquireFile.  The new constant to use to
  generate thee files is DTWAIN_TGA_RLE.

- Added generation of BMP Run Length Encoded files to DTWAIN_AcquireFile.  The new constant to use to
  generate these files is DTWAIN_BMP_RLE.  Usage of RLE reduces the size of the resulting BMP file.
  Note that this is only available for 8 bit-per-pixel BMP files.
 
- Fixed issue with DTWAIN_SelectOCREngine not showing product name of available OCR engines.

- Added entry to twaininfo.txt to properly handle text obtained from 1 bit-per-pixel OCR-ed images.

- Added versioning check for twaininfo.txt.


5.4.4

- Fixed possible null pointer access when retrieving the default TWAIN Source.



5.4.3

- Updated page handling logic when scanning duplex pages.  

The number of pages specified by the DTWAIN_Acquire...() family of functions will automatically be doubled
when the following occurs:

1) acquiring duplex pages 
   (DTWAIN_EnableDuplex has been called to set the duplexer to TRUE, or the device's only method of acquiring 
    images is duplex)

and

2) The TWAIN Source user-interface is disabled.

For 2) if the user interface *is* enabled, there is no way for DTWAIN to know if the user selected or deselected the duplex
option (if one exists), so the page count cannot be automatically doubled.  In this case, the driver is responsible for the 
duplexing to work properly if the user desired to enable duplexing.

- Updated the copyright notices on source files, DLL's, etc. to the year 2024.


5.4.2

- Upgraded following internal image, compression, and cryptography libraries:

      crypto++ --> 8.9
      libtiff  --> 4.6
      libpng   --> 1.6.39
      libjpg (IJG) --> 9e
      libwebp  --> 1.3.2
      openjpeg --> 2.5.0
      zlib     --> 1.3.0.1
      
- Dynarithmic Software version information is now embedded in generated JPEG-2000 image files.

5.4.1

- Address issue with DTWAIN_SetTwainLog() and resetting the logging options to "no logging" if 
  logging has already been set.

- Optimize various calls to the internal API functions.


5.4.0

- DTWAIN Version numbering will now use 3 components: 
	  MajorVersion.MinorVersion.PatchVersion

- For DTWAIN_AcquireFile(), DTWAIN_AcquireFileEx(), added image file type DTWAIN_ICO_RESIZED
  and DTWAIN_WBMP_RESIZED.  These are Windows ICON file and Wireless Bitmap files, respectively,
  that are a resized version of the image acquired if the image's original width and/or height 
  exceeds a length of 255.  The image will be resampled to a 255 x 255 bitmap if either 
  the width or height exceeds 255.

  This differs from DTWAIN_ICO and DTWAIN_WBMP in that if the image's width or height acquired 
  exceeds 255, the image will be invalid and thus no image file will be created.

- Added DTWAIN_SelectSource alternative functions:

	DTWAIN_SelectSourceByNameWithOpen       
	DTWAIN_SelectSourceByNameWithOpenA      
	DTWAIN_SelectSourceByNameWithOpenW      
	DTWAIN_SelectSourceWithOpen             
	DTWAIN_SelectDefaultSourceWithOpen      

  Each of these functions allow selecting a TWAIN source with the option to also open the 
  source once it has been selected.  For example:

        DTWAIN_SOURCE source = DTWAIN_SelectSourceWithOpen(FALSE);  // Select, but do not open the source
	DTWAIN_OpenSource(source); // Open the selected source

  This will easily allow applications to just select the source, if there is a possibility
  that opening the source after selection may cause issues (hardware issue, driver issue, etc.).

  These new functions should be used to control opening a selected source instead of the 
  DTWAIN_OpenSourcesOnSelect() function, as DTWAIN_OpenSourcesOnSelect() is a global setting.  
  The new DTWAIN_SelectSource...WithOpen() functions will not use the DTWAIN_OpenSourcesOnSelect()
  setting.

- Added the following select source options to functions DTWAIN_SelectSource2() and DTWAIN_SelectSource2Ex():

     DTWAIN_DLG_OPENONSELECTON  - Open source if selected
     DTWAIN_DLG_OPENONSELECTOFF - Do not open source if selected

  These new options now control if a selected source will be opened or not opened on selection.  If both
  options are used, DTWAIN_DLG_OPENONSELECTON is assumed.



5.3.0.8 

- Fixed possible crash with DTWAIN_SetMultipageScanMode and acquiring to multipage image files 
  when attempting to obtain the current TWAIN session handle.



5.3.0.7 

- Fix issue with DTWAIN_SetAcquireArea when resetting the acquisition area of interest.



5.3.0.6 

- Fix issue with DTWAIN_SelectDefaultSource selecting a null TWAIN data source.



5.3.0.5 

- Add DTWAIN_IsSourceValid() function to explicitly test to see if the DTWAIN_SOURCE is valid.

- Add DTWAIN_DeleteDIB() to allow deletion of Device Independent Bitmap image data.

- Add a refresh parameter to DTWAIN_GetSourceDetails()

- Introduce DTWAIN_EnableTripletNotify() to allow DTWAIN_TN_TWAINTRIPLETBEGIN and DTWAIN_TN_TWAINTRIPLETEND 
  notifications to be sent to the application.   

- Make corrections to the Visual Basic demo program for 64-bit DTWAIN.



5.3.0.4 

- Allow DTWAIN_IsTwainAvailable() to properly detect TWAINDSM.DLL for 32-bit applications.

- Address issues with DTWAIN_TN_PAGEFAILED on page acquisition failure.

- Address issue with string-based TWAIN capabilities not being retrieved correctly.

- Ensure DTWAIN_TN_PAGExxxx notifications are sent on every successful page acquisition.

- Add DTWAIN_GetSessionDetails and DTWAIN_GetSourceDetails to return a JSON string describing the TWAIN session
  and TWAIN sources, respectively.

- Internal source code changes.



5.3.0.3		  

- Handle issue WIA-based drivers that close the user-interface of the TWAIN source before issuing a request to
  start acquiring pages.  

  Previously, many WIA drivers would not acquire an image depending on the program
  setup (GUI programs would usually work correctly, console applications most times would not start the 
  acquisition process).  You must use the latest dtwain32.ini and dtwain64.ini files for the WIA drivers
  to work properly.

- For acquiring to files, if the bits-per-pixel of the original image data does not match the required
  bits-per-pixel of the image file type, the image will be resampled to fit the bits-per-pixel of the image
  file type.  

  For example, if a TIFF Group 4 file is specified (which can only be 1 bit-per-pixel), but the original image
  obtained by the device returns an 8 bit-per-pixel image, the 8-bit-per-pixel will be automatically resampled
  to 1 bit-per-pixel.  This change will allow less bit-per-pixel matching failures if a device returns an 
  "incorrect" image with the wrong number of bits-per-pixel.

- Reduced the size of the DTWAIN DLL's by approximately 4 MB.  

- Internal library changes:  
    a) Removed unused FreeImage code.  
    b) Added CXImage code to allow for more bitmap transformations to be done.


5.3.0.2		  

- Internal TWAIN message loop has now been restructured to start before the source UI is displayed.

- For 64-bit drivers -- General fixes for various functions that query the state of the TWAIN device
  (for example DTWAIN_IsFeederLoaded(), DTWAIN_IsDeviceOnLine()).

- When specifying the number of pages to acquire for duplex scanning, if the number of actual images 
  acquired is greater than the number of pages that will be acquired, some sources will hang.  This has been fixed.

- Change to DTWAIN_SetDefaultSource() to use the setting in DTWAIN32.INI and DTWAIN64.INI files.
  This change was necessary since the current operation of DTWAIN_SetDefaultSource() is no longer supported by the 
  TWAIN specification 2.x.  Thus the default source product name is now kept in the DTWAIN32.INI and DTWAIN64.INI 
  files under the [Sources] section.


5.3.0.1		  

- Fix issue with buffered mode file transfers.


5.3.0.0		  

- Initial support for latest TWAIN 2.5 capabilities (mostly Image Addressing).

- Support for Memory File Transfers (see the new DTWAIN_USEMEMFILE file flag for DTWAIN_AcquireFile).

- Internal changes to DTWAIN Array handling.

- Building the DTWAIN source code now requires Visual Studio 2019 and above.

- Updated LibPng to version 1.6.38

- Updated LibTiff to version 4.4

- Added demo projects.

- Initial release of the C++ object-oriented wrapper of DTWAIN.

- Miscellaneous bug fixes.
						

5.2.0.10		  

- Fixed issue when acquiring a file using memory/buffered transfer, where an invalid bitmap was sent to the
  application to query if the bitmap should be discarded.


5.2.0.9		  

- Added DTWAIN_SysInitializeNoBlocking() --

  This new function works identical to DTWAIN_SysIntialize, except that DTWAIN_SysInitializeNoBlocking 
  will not display the "DTWAIN Resource Error" message box if the DTWAIN resource text files cannot be found.  
  This will allow DTWAIN to not block the application if there is a resource error.

- Updated blank page handling.

  Prior versions of the blank page handling always tested for a blank page for the image that is directly coming
  from the TWAIN device, and a second time a test for blank page after the image has been cropped and resampled.  
  This version now gives the ability to test for a blank page in either or both scenarios.  

  The new DTWAIN_SetBlankPageDetectionEx sets up testing for blank pages using the method outlined above.

      DTWAIN_SetBlankPageDetectionEx(DTWAIN_SOURCE Source, DTWAIN_FLOAT threshold, LONG autodetect, LONG detectOpts, DTWAIN_BOOL bSet)

  Note that this function works similar to the DTWAIN_SetBlankPageDetection function, except for the new detectOpts parameter.
  The detectOpts parameter is a combination of the following:

  DTWAIN_BP_DETECTORIGINAL - Detect blank pages for the original image that the device generated.
  DTWAIN_BP_DETECTADJUSTED - Detect blank pages for the adjusted image (after cropping, rescaling etc.)
  DTWAIN_BP_DETECTALL	   - Detect blank pages for both the original and adjusted images (this is the legacy behavior).

- Corrected blank page handling for gray-scale images

  If blank page handling is turned on, and the image acquired is an 8-bit that requires a palette to define the colors used,
  the blank page detection will detect pages that have a single solid color within the threshold given by the caller.  

  For example, if the threshold limit is 98%, and 98% or above of the entire page is red, the page is now considered blank.  

- Added missing ANSI and Wide functions for DTWAIN_Range... and DTWAIN_Frame... functions that have 
  pointers to strings as parameters.

- Added function DTWAIN_GetActiveDSMPath, DTWAIN_GetActiveDSMPathA, and DTWAIN_GetActiveDSMPathW to return the 
  full path of the TWAIN DSM that is being used.

- Added function DTWAIN_GetTwainStringName, DTWAIN_GetTwainStringNameA, and DTWAIN_GetTwainStringNameW
  to return a string version of one of the triplet components.  This function is merely a utility function that allows 
  you to get the string versions of the values used in the DG/DAT/MSG triplet combination.

      For example: 
          char buffer[100];    
          DTWAIN_GetStringNameA(DTWAIN_DATNAME, 0x0009, buffer, 100);

      will have buffer set to "DAT_USERINTERFACE", since 9 is the TWAIN Data Argument Type (DAT) for the DG_CONTROL name 
      associated with value 9 (see the twain.h header file provided in the include path for DAT names and their 
      corresponding values).

      The first parameter can be one of the values below:
      DTWAIN_DGNAME - The data group name as a string
      DTWAIN_DATNAME - The data argument type as a string
      DTWAIN_MSGNAME - The message name (for example, "MSG_GET")
     

- Formerly undocumented DTWAIN_AddPDFTextEx is now available.  The function adds text to a PDF page 
  given a DTWAIN_PDFTEXTELEMENT.

- DTWAIN_SysIntialize and DTWAIN_SysInitializeNoBlocking() will now set DTWAIN_GetLastError() to -1051
  if the DTWAIN resource text files cannot be found.  If DTWAIN_SysInitialize or DTWAIN_SysInitializeNoBlocking 
  return 0, your application should immediately call DTWAIN_GetLastError() to confirm that the error received 
  is -1051, indicating that the resources could not be found.

- Fix and update the C#, Visual Basic Net, and the C/C++ LoadLibrary/GetProcAddress wrappers (using the 
  LoadLibrary and GetProcAddress wrappers, no import library is required by C and C++ applications 
  that wish to use the DTWAIN library)


5.2.0.8
- Corrected issue with single page PCX files not being generated.
- Corrected issue with acquiring to text files with no available OCR support library.


5.2.0.7
- Corrected issue with duplex scanning only scanning the first page if pending image count was not 0.


5.2.0.6		  
- Added following function:
  DTWAIN_ConvertDIBToBitmap -- Converts a Device Independent Bitmap to a Device Dependent Bitmap

- The functions were missing from the .DEF files:
  DTWAIN_ArrayGetSourceAt
  DTWAIN_GetTwainAppIDEx
  DTWAIN_GetSourceIDEx

- The dtwainx.h header file now includes <commdlg.h> and replaces LPCBYTE with const BYTE*.
  The reason for this is that if WIN32_LEAN_AND_MEAN are defined by the application, and 
  dtwain.h is #included after this definition, the OPENFILENAME and LPCBYTE were not defined.

- Miscellaneous code refactoring.


5.2.0.5		  
- Added following functions:
  DTWAIN_ArrayGetSourceAt -- Use this function in conjunction with DTWAIN_EnumSources to easily retrieve each TWAIN Source found.
  DTWAIN_GetTwainAppIDEx --  Use this function to fill in a TW_IDENTITY structure that describes the TWAIN application ID values.
  DTWAIN_GetSourceIDEx   --  Use this function to fill in a TW_IDENTITY structure that describes a TWAIN Source.

  The following set of functions handling the CAP_AUTOMATICSENSEMEDIUM capability are added:

  DTWAIN_IsAutomaticSenseMediumEnabled
  DTWAIN_IsAutomaticSenseMediumSupported
  DTWAIN_EnableAutomaticSenseMedium
 

5.2.0.4		  
- Changed DTWAIN ANSI and wide string functions to use the "length" parameters correctly.

- Updated dtwainx.h and dtwstrnfn.h to add missing exported API function declarations.

- Updated the C++ interface found in the \language_bindings_and_examples\C_CPP_DynamicLoad\ directory.

- Updated copyright message to stated year 2021.


5.2.0.3		  
- Added functions DTWAIN_SelectSource2Ex to allow customization of the files listed in the TWAIN Select Source dialog box.
  Customization includes including and excluding TWAIN source names in the dialog box, as well as aliasing your own names for
  a device name.  This function can be used to only display devices that are pertinent for your application.

  Example:
    DTWAIN_SOURCE source = DTWAIN_SelectSource2Ex(NULL, "Custom Title", 0,0, NULL, "Scanner1|Scanner2", "Scanner3=My Scanner",
                                                  DTWAIN_DLG_CENTER | DTWAIN_DLG_USEEXCLUDENAME | DTWAIN_DLG_USENAMEMAPPING);

  The code above will display the TWAIN Select Source dialog, centered on the screen.  If any devices have the product name 
  "Scanner1" or "Scanner2", they  will be removed from the dialog.  In addition the device named "Scanner3" will be named "My Scanner" 
  in the dialog box.  

  Note that you could have done this in a much longer way by calling DTWAIN_EnumSources, gathering all the product names, and 
  displaying the products you want as selections by creating your own dialog or user-interface.  The DTWAIN_SelectSource2Ex is
  just a much simpler way of achieving this goal.

  In addition, there are functions DTWAIN_SelectSource2ExA and DTWAIN_SelectSource2ExW that represent the ANSI and Wide versions
  of the function. 


5.2.0.2		  
- Fixed DLL Version Information in the DLL resources.

- Fixed generation of multipage TIFF files if the compression used on pages will vary.  This fix required 
  patching the FreeImage source code. 

- Fixed DTWAIN_SetTiffCompressType to properly handle non-multipage and multipage TIFF types.

- Added function DTWAIN_SetDSMSearchOrderEx to allow applications to customize where DTWAIN will search for the 
  TWAIN Data Source Manager.  This differs from DTWAIN_SetDSMSearchOrder in that the Ex version will now allow
  searching in a custom directory.		  

- Added initial support for MSG_GETHELP, MSG_GETLABEL, and MSG_GETLABELENUM using DTWAIN_GetCapValues and related functions.
  Note that these messages were always available using the lower-level DTWAIN_CallDSM function, but now the library has made
  these messages available using the DTWAIN_GetCapValues function.

- Changed DTWAIN_IsFeederSupported to do a more thorough test to see if a feeder is supported instead of just checking
  for the feeder being enabled.

- Fixed issue with MSG_SETCONSTRAINT message not being recognized in call to DTWAIN_SetCapValues.

- Added DTWAIN_GetLastError() return code of -1050 to denote that Source selection has been cancelled from the TWAIN dialog.  
  Previously the cancellation was reported as an INVALID DTWAIN SOURCE.  This did not affect applications, since the 
  TWAIN Source is actually NULL if the TWAIN dialog is cancelled, but this additional code is added for clarity.

- DTWAIN Log now shows local time stamp intstead of UTC.
					   
- Other miscellaneous fixes


5.2.0.1
- Fix incorrect version number in DLL resources

- Add missing source file ctlacquireaudio.cpp to source build project


5.2.0.0
- Added support for audio file transfers using the TWAIN capability ACAP_AUDIOXFER.  
  New functions are DTWAIN_AcquireAudioNative, DTWAIN_AcquireAudioFile, DTWAIN_AcquireAudioFileA, DTWAIN_AcquireAudioFileW

- Fixed issue with multipage image files only saving the last page.


5.1.0.9
- Added DTWAIN_SetTwainDialogFont() to adjust font used in TWAIN Select Source dialog (only is available
  when calling DTWAIN_SelectSource2() function)  Usage:

	DTWAIN_SetTwainDialogFont(HFONT font)

  where HFONT is a handle to a Windows HFONT.  If font is 0, the default font (MS Sans Serif) is used.

- Added test for CAP_SHEETCOUNT to control the number of pages that will be acquired.

5.1.0.8
- Removed initial slow TWAIN capability retrieval and replaced with fast capability retrieval.
- Fixed issue with CAP_FEEDERLOADED being considered an unsupported capability for some TWAIN devices.
- Added additional language resource for Portuguese-Brazilian strings (thanks to user mauriciofaria).
- Visual Studio 2019 solution added (thanks to user Dcreeron).

5.1.0.7
- Fixed issue with program opting to discard the first page of a multi-page acquisition.

5.1.0.6
- Added custom code for TWAIN drivers that erroneously return TWRC_CANCEL when the user interface is closed.
- Updated search logic when attempting to find / load the TWAIN Data Source manager
- Added DTWAIN_GetLibraryPath function to return the path of the loaded DTWAIN Dll

5.1.0.5
- Minor source code changes.  Removed LPGL wording from source files.

5.1.0.4
- Fix for erroneous return code when multipage PCX (DCX) files after saved

5.1.0.3
- Add DTWAIN_...Ex() functions that return a DTWAIN_ARRAY.  These functions are simpler versions of the DTWAIN 
  functions that accept LPDTWAIN_ARRAY as a parameter.  This makes it simpler for languages such as Python and
  others that have issues with pointer arguments.  Thus instead of having to do something like this:

      DTWAIN_SOURCE Source;
      DTWAIN_ARRAY Array;
      //...
      DTWAIN_EnumOrientations(Source, &Array)...

The call can now be this:

      DTWAIN_SOURCE Source;
      //...
      DTWAIN_ARRAY array = DTWAIN_EnumOrientationsEx(Source);

Since DTWAIN_ARRAY is actually an integer (32-bit or 64-bit, depending on the program's bit-ness), the calling 
application can simply treat the DTWAIN_ARRAY as an integer type.

For functions that already have an Ex() at the end of the function name, an Ex2() version was created, for example,
     DTWAIN_EnumSupportedCapsEx2()
     
     
5.1.0.1
- Add all supported PDF page dimensions to twaininfo.txt.  This allows customization of the PDF creation with
  respect to the page sizing (you can add your own definitions).
- Update sources to output Visual C++ 2019 compilation messages.

5.1.0.0
- Update LibTiff to version 4.0.10
- Update LibPNG to version 1.6.37
- Now requires application to call DTWAIN_UseMultipleThreads if one DTWAIN session will be used across multiple threads.
- Speed up processing DTWAIN functions when using DTWAIN in a single thread.
