Setting scan coordinates in device options on pyinsane
Question: I use Sane's command line utility (`scanimage`) in order to scan films from
the transparency unit of my scanner. Here is the command that I have been
using with success:

    
    
    scanimage --device-name pixma:04A9190D \
    --source 'Transparency Unit' \
    --resolution "4800" \
    --format "tiff" \
    --mode "color" \
    -l "80.6" -x "56.2" -t "25.8" -y "219.2" \
    > scan.tiff
    

I have decided to move this to Python code, using `pyinsane` in order to
enable further integration with my image-processing workflow. This should
supposedly give the following in Python code:

    
    
    import pyinsane.abstract as pyinsane
    device = pyinsane.get_devices()[0]
    
    device.options['resolution'].value = 4800
    device.options['mode'].value = 'Color'
    device.options['source'].value = 'Transparency Unit'
    
    # Setting coordinates to non-integers fails
    device.options['tl-y'].value = 25.8
    device.options['tl-x'].value = 80.6
    device.options['br-y'].value = 219.2
    device.options['br-x'].value = 56.2
    
    scan_session = device.scan(multiple=False)
    try:
        while True:
            scan_session.scan.read()
    except EOFError:
        pass
    image = scan_session.images[0]
    

But my first trials have been unsuccessful because I can not figure out how to
set the scan coordinates `pyinsane`. As you see, I have found the appropriate
options, but I don't know what unit they are in. `scanimage` takes the
coordinates in millimetres by default, but `pyinsane` only takes integers. I
have tried using pixel coordinates to no avail. I wonder what units the
coordinate parameters take, and whether I am using them in the right order.


Answer: pyinsane's option descriptions actually say the values are in milimeters:

    
    
    Option: br-x
      Title: Bottom-right x
      Desc: Bottom-right x position of scan area.
      Type: <class 'pyinsane.rawapi.SaneValueType'> : Fixed (2)
      Unit: <class 'pyinsane.rawapi.SaneUnit'> : Mm (3)
      Size: 4
      Capabilities: <class 'pyinsane.rawapi.SaneCapabilities'> :[ Automatic, Soft_select, Soft_detect,]
      Constraint type: <class 'pyinsane.rawapi.SaneConstraintType'> : Range (1)
      Constraint: (0, 14160319, 0)
      Value: 20
    

But they are not! I divided the range maximum for `br-x` variable by the width
of the scanning area of my scanner, and I got to the number 65536 (which is
2^16). Setting the coordinates to the millimetre value times 65536 works.
Maybe these values define the number of steps of the stepper motor?

Also not that while scanimage interprets the `-x` and `-y` switches as width
and length, and the `-l` and `-t` switches as offset, pyinsane takes bottom-
right x (`br-x`), top-left y (`tl-y`), etc.

