dynarithmic / twain_library

Dynarithmic TWAIN Library, Version 5.x
Apache License 2.0
56 stars 24 forks source link

Error code -1018 (DTWAIN_ERR_FILE_FORMAT) #71

Closed HezinTUKE closed 1 year ago

HezinTUKE commented 1 year ago

Hi, I want to scan files like uncompressed TIF but I keep getting the error -1018 after getting the source .

My code :

pub fn DTWAIN_AcquireFile(&self, lib : &Library) -> Result<bool, Box<dyn std::error::Error>> {
        unsafe {
            let acquire_file: libloading::Symbol<unsafe fn(*mut i32, String, u16, u32, i32, i32, bool, bool, Option<i32>) -> bool> = lib.get(b"DTWAIN_AcquireFile").unwrap();

            Ok( acquire_file(self.source, "testScanTiff.tif".to_string(), 600, 1 | 4 , 1000, -1, false, true, None))
        }
 }

Help me please =)

dynarithmic commented 1 year ago

You will have to produce a TWAIN log (DTWAIN_SetTwainLog) and specify to log to a file with full call stack to see exactly if you are passing correct values to the DTWAIN_AcquireFile function. The only reason for the failure is if the file type given for an uncompressed TIFF file is invalid.

I am assuming this is python? I am not a python expert, so I do not know exactly your method of calling DTWAIN_AcquireFile well enough to understand what you are doing with the code. That's why you need to produce a log to see the call to DTWAIN_AcquireFile and check the parameters that are passed. If the filetype parameter, (parameter 3) is not 600, then you know you have to fix the call in your code (but I do not know how to do this, since again, I am not a python programming expert).

Also, to double check, try the DTWDEMO.exe program to ensure you can acquire to an uncompressed TIFF file. The demo program allows acquire to file, and you select the type as uncompressed TIFF.

dynarithmic commented 1 year ago

Also, the call stack in the log is the best way to determine if you are calling the DTWAIN functions correctly, especially if you are not using C or C++. The computer language you're using needs to verify that you are calling the functions correctly, and there are many languages that can interface to DTWAIN, but the responsibility of creating the interface properly is up to the programmer.

DTWAIN does have C#, Java, VB.Net, and other language interfaces. However for python (if it is python), the interface merely is a group of constants that match the ones defined by DTWAIN -- there is no actual functional interface (like the C# or Java interfaces). Since you created the interface yourself, you need to verify that the parameters being sent are correct, and you can only know that by looking at the log file and searching for DTWAIN_AcquireFile in the log and checking the parameter list.

HezinTUKE commented 1 year ago

Thanks for reply 😊, this is Rust =) . I don't know how but it's working already 😐 . But after each scanned page DTWAIN opens "Save As" window even if this one has not parameter 8 ( DTWAIN_USEPROMPT ) .

dynarithmic commented 1 year ago

Never used rust, so thanks for the info. I may have to learn it just to make a binding for it. 😊

From what I see in your code, you are specifying 1 | 4 for the file flags. From the list of options, this would be native mode and use compression. What you want are DTWAIN_USELONGNAME (64), with an optional DTWAIN_CREATE_DIRECTORY (512) if you want a directory automatically created. So the flags parameter should be 64 | 512.

The prompt is displayed if the flags cannot determine how the file is to be saved (by name or by prompt), and 1 | 4 does not specify the way in which the file is saved.

Here are the list of flags:

#define DTWAIN_USENATIVE           1
#define DTWAIN_USEBUFFERED         2
#define DTWAIN_USECOMPRESSION      4
#define DTWAIN_USEMEMFILE          8
#define DTWAIN_USENAME            16
#define DTWAIN_USEPROMPT          32
#define DTWAIN_USELONGNAME        64
#define DTWAIN_USESOURCEMODE      128
#define DTWAIN_USELIST            256
#define DTWAIN_CREATE_DIRECTORY   512
HezinTUKE commented 1 year ago

Oh ! Thank u very much, because in documentation are another values : image

HezinTUKE commented 1 year ago

I set a directory path and set option 64 DTWAIN_USELONGNAME which assigns a filename but after I have no files.

Also i used DTWAIN_SetFileAutoIncrement but it was not working too 😔 .

pub fn DTWAIN_AcquireFile(&self, lib : &Library) -> Result<bool, Box<dyn std::error::Error>> {
        unsafe {
            let acquire_file: libloading::Symbol<unsafe fn(*mut i32, String, u16, u32, i32, i32, bool, bool, Option<i32>) -> bool> = lib.get(b"DTWAIN_AcquireFile").unwrap();

            Ok( acquire_file(self.source, "C:\\Users\\user\\Desktop\\test\\TIFF\\FILE000.TIF".to_string(), 600, 64 | 512 , 1000, -1, false, true, None))
        }
    } 
dynarithmic commented 1 year ago

Unfortunately the documentation needs to be updated, as those values were used in old versions of DTWAIN. I would suggest using the constants you see in dtwaindefs.h if you are going to interface to DTWAIN.

Also, it is impossible for me to know exactly why the file is not created for several reasons: 1) I do not know if the file path exists, since I do not have access to your system.
2) DTWAIN does not create files if the directory is inaccessible, or you don't have permissions to the file, etc.

This is where the log is highly important. It will tell you exactly what was done in attempting to create and save the file. So you will need to generate a log and inspect what happens during the call to DTWAIN_AcquireFile. If you have a log produced, then I can probably figure out what is going on as to why the file was not created.

Also, the full source code is available. If you can debug C++ code, you can use the debug DLLs found here for 32-bit and here for 64-bit.

dynarithmic commented 1 year ago

Note:

I updated the online help documentation to reflect the constant values for DTWAIN_AcquireFile.

Thanks for pointing out the issue.