In my previous post I mentioned that while VueScan has the option to use manual or automatic focus, it doesn't actually change how the scanner operates. This post is proof that it doesn't do anything. To be clear, as far as I can tell, the v550 does not support changing focus at all. This is not a shortcoming of VueScan, aside from presenting an option when it shouldn't.
VueScan has a drop down for autofocus with the options of "Always", "Scan", "Preview" and "Manual". Selecting "Manual" adds a slider that can be used to set the focus from -1.0 to 1.0. For my tests I compared the commands sent to the scanner with it set to "Always" and "Manual" at both -1.0 and 1.0.
Epson's v550 scanner driver is split into an open source part (named epkowa) and a v550 specific
proprietary plugin. Both of these are installed as shared libraries at
/usr/lib/sane/libsane-epkowa.so
and
/usr/lib/iscan/libiscan-plugin-perfection-v550.so
, respectively. After digging around a
while I discovered that the open source driver communicates to the scanner in a protocol called
ESC/I which doesn't seem to be documented anywhere. Some manuals make reference to it
though. The v550 does not implement ESC/I directly, so the proprietary plugin interprets the ESC/I
and converts it to the scanner's native protocol. This is why it's referred to as an interpreter in
the /usr/var/lib/iscan/interpreter
config file.
Running
$ strace -P /usr/lib/sane/libsane-epkowa.so ./vuescan
and
$ strace -P /usr/lib/iscan/libiscan-plugin-perfection-v550.so
./vuescan
shows that while VueScan does not use the open source SANE
interface, it does use the proprietary plugin. Fortunately, since the main epkowa driver is open
source, the API for that plugin is documented. This
means I can create a shim that intercepts and logs calls to the shared library (see more details here).
You can find the source for my shim here. It's pretty simple and just logs everything being sent to/from the scanner to stderr with a R or W prefix to indicate reads/writes.
I ran VueScan both in normal scanning mode and in preview mode collecting logs scanning with autofocus, with manual focus at the minimum, and with manual focus at the maximum. The first thing that's clear is that there is no difference between the minimum and maximum focus:
$ diff close_focus.log far_focus.log && echo Same
> Same
There is a slight difference between autofocus and the manual focus:
$ diff close_focus.log auto_focus.log
> W: 1b 65
> R: 6
> W: 1
> R: 6
The first line is ESC-e which is the command to control an extension. Extensions refer to extra parts like automatic document feeds or the transparency scanning unit. It then reads back 6, writes 1 and reads another 6. I'm not sure what the one ands sixes mean, but the open source driver call this function when enabling an extension. My guess as to what's happening is VueScan has a common code path for turning on autofocus that starts by enabling the transparency unit then does something device specific (which is nothing for this scanner). But that's just a guess; I have no data to back that up. In any case, it isn't doing anything to change how the scanner focuses.
I tried but neither works in this case. Since VueScan is loading the shared library directly
from it's absolute path with dlopen()
, LD_PRELOAD doesn't have any effect. From
man 3 dlopen
:
If filename is NULL, then the returned handle is for the main program. If filename contains a slash ("/"), then it is interpreted as a (relative or absolute) pathname. Otherwise, the dynamic linker searches for the object as follows (see ld.so(8) for further details)
Since the path does have a slash, the dynamic linker does not search for the object and thus
LD_PRELOAD
is not used
I tried using ltrace
but could not get it to work. Perhaps it has issues with
dlopen
as well?