Jürgen Ernst, Dipl.-Ing.(FH) HomepageKontaktInformationLinksNews
Hard- & Software-EntwicklungInformation: SANE backend for

Information: SANE backend for "CanoScan LiDE 70 / 600F"

Latest results

You can find the latest source tarballs at

sane-backends-1.0.32 has been released.

sane-backends-1.0.31 has been released.
### Backends
- adds the "canon_lide70" backend

User feedback

I report success using your script: canoscan600f-20130118.pl .

Hardware: Raspberry Pi 2
Operating system: Raspbian GNU/Linux 8.0 (jessie)
Installing the the package "libdevice-usb-perl-0.36-3+b1" was a necessary step.

Results are quite good, and I appreciate being able to use the scanner on Linux.

Older results

Here's my perl script for CanoScan LiDE 600F which is able to scan a whole page at 300 dpi (=25MB). Without gamma correction at the moment. Use gimp to fix this!
The script must be run as root. If it is stuck simply replug. Output file is "scan.ppm".
canoscan600f-20130118.pl (36.7 kB)

Only for testing: a perl script for CanoScan LiDE 70 which isn't able to scan a page yet, but it's getting closer. Try and report your findings.
The script must be run as root. If it is stuck simply replug.
canoscan70-20130118.pl (34.0 kB)

Prerequisites: This script needs package Device::USB from CPAN.
If you haven't installed it yet you'll get an error stating:
Can't locate Device/USB.pm in @INC (@INC contains: /etc/perl...
To fix this:
1. login as root in xterm
2. Then first invoke
perl -MCPAN -e "install Inline::C"
and then invoke
perl -MCPAN -e "install Device::USB"
3. This will only compile if gcc is installed.
4. If it didn't work you can send me a log what 2. prints out. Then I can try to find the fault and give you help for the next step

Scan modes: it's 300 dpi only! Colour space is RGB. Image file format of the output is portable pixmap (PPM) related to the Netpbm project. Can be read and converted by almost all image manipulation programs.

Scan sizes:
DIN A4: 4980 x 7020 dots (210 x 297 mm) This is the default!
Letter: 5100 x 6600 dots (17 x 22 inches)
(Frame coordinates are represented using 600 dpi according to SANE standard)
You can select the scan size by adding or deleting char # at the beginning of line 1137 or 1138.
If you want more control you can change the numbers defining the scan area:
x1 and y1 are defining the coordinate of the top left corner
x2 and y2 are defining the coordinate of the bottom right corner
Hint: add a copy of the wanted line and modify the copy instead. Keep the original lines to save the coordinates of the maximum area.
Scan resolution is 300 dpi only. Don't change this! Altering it won't change the scan but internal calculations will get worse.

Gamma correction: not supported at the moment! This means the scan is not calibrated. Colours will look pale and imbalanced. But you can use Gimp to fix this. Open scan image with Gimp, choose menu "Colors" -> "Levels..." and then click button "Auto" or adjust them manually.

And don't forget: this is alpha software which is in an early stage of development. You are on the bleeding edge.

License: GNU General Public License (GPLv2 or later).

No warranty: the author is not liable to you for damages, including any general, special, incidental or consequential damages arising out of the use or inability to use the program (including but not limited to loss of data or data being rendered inaccurate or losses sustained by you or third parties or a failure of the program to operate with any other programs), even if the author has been advised of the possibility of such damages.


If you want to help this project please send an email to me (Jürgen Ernst).

C source code of my porting attempt can be found here:
Code for Canon LiDE 600 can be found in folder backend:
Files: canon_lide-common.c and canon-lide.c

Developing the SANE backend

SANE stands for "Scanner Access Now Easy" and is an application programming interface (API) that provides standardized access to any raster image scanner hardware (flatbed scanner, hand-held scanner, video- and still-cameras, frame-grabbers, etc.).

The SANE API is public domain and its discussion and development is open to everybody.

You can find more information regarding the SANE project on its official homepage at http://www.sane-project.org.

The flatbed scanner

Features: Ergonomic, 3-Way design, Film Adapter Unit for 35mm transparencies, FARE and QARE Level 3 dust/scratch removal, 4800 x 9600dpi*, 48 bit colour depth, USB 2.0 Hi-Speed, Scan to PDF, Multi-photo mode, 7 EZ buttons, Comprehensive software package.

The CanoScan LiDE 600F is a very good scanner. But it has the disadvantage that Canon is unwilling to release the necessary documentation to enable a Linux driver and SANE backend to be written.

So I decided to write a SANE backend for linux on my own.

Identification of the protocol

The CanoScan LiDE 600F is compatible to the CanoScan LiDE 600 and the difference is simply an additional Film Adapter Unit. So the chips for the LiDE 600F are known, but are not known to be compatible with SANE-supported chips. You can find this information and more here.

On my computer SANE (v1.0.18) reported this (13.8 kB) after starting the command "sane-find-scanner -v -v".

As this scanner has an USB interface a good start would be to complete a small scan with an USB sniffer to log the traffic on the USB bus for that device. That may allow identification of the protocol.

To do this I had to create a partition with Win XP on my hard drive. Then I installed the Canon software from CD. After verifying that the scanner is working as it should I downloaded an USB sniffer. I used benoit's USB sniffer.

Here are some original log files from the sniffer:

Simply plugged the scanner in, calibration process recorded
usbsnoop1.zip (196 kB)

Preview scan with empty white page
usbsnoop2.zip (3.9 MB)

Scan with 150 dpi (colour, 1276 x 1384 pixel)
usbsnoop3.zip (4.9 MB)

Scan with 150 dpi (grey, 1276 x 1384 pixel)
usbsnoop4.zip (8.8 MB)

Scan with 150 dpi (colour , 248 x 267 pixel)
usbsnoop5.zip (2.0 MB)

To simplify the work with the log files above I wrote "parselog1.pl" and "parselog2.pl" to convert them into a format for better parsing and human reading. A conversion of "usbsnoop1.zip" can be found in "snoop1.zip". And "usbsnoop2.zip" is in "snoop2.zip" and so on.

Script to convert the log files to simple format
(you have to give the log filename as parameter. Output is displayed to STDOUT so you'll have to redirect it to a file)
parselog1.pl (3.6 kB)
(as parselog1.pl but it omits dummy bulk data transmissions -> smaller file)
parselog2.pl (3.9 kB)

New simplified log files (output from parselog2.pl)
snoop1.zip (67 kB)
snoop2.zip (2.3 MB)
snoop3.zip (1.7 MB)
snoop4.zip (6.2 MB)
snoop5.zip (1.4 MB)

Next is a method to send data to and receive data from the scanner. I'm using perl as my favorite programming language and so I installed the package Device::USB from CPAN to get easy access to libusb.

I programmed the script "canonusb3.pl" to load a log file and send the same data to the scanner. The first result is: it works! I managed to access the scanner. It made some moves forth and back, turned on the light and moved about 1 inch forward. An I/O-Error stopped the script but as a first result this is great!

Script to access scanner and replay log file
(you have to give the log filename as parameter, tries to replay whole log)
canonusb3.pl (4.4 kB)

I modified the script to replay sections of the log. Now you can specify start URB and end URB as additional parameters.

Script to access scanner and replay log file (start URB + end URB)
canonusb4.pl (4.7 kB)

CP2155 scanner chip

The scanner chip has a page with 256 registers. Each byte can be set and read with a single command. At calibration there is a command sequence to get the content of the whole page. I made a script to get this bytes too.

Script to get whole registerpage 0x00..0xfe
registerpage.pl (3.0 kB)
Here is the output you'll get for LiDE 600F and LiDE 70
registerpage.txt (1.7 kB)

Script to poll one single register
pollregister.pl (3.3 kB)
Parameter is register in hex. (e.g. 91)

My current knowledge of CP2155 registers can be found in register.txt.


To replay the log the scan head has to be put to it's start position. I can't do this with my script at the moment. You must use your scanner software (Windows) to move the head back to the start position.

The script has to be run as root. Otherwise it gets no access to the device. Okay you can set permissions but it's silly to do this. If you unplug and replug the scanner frequently, hotplug will set up a new usb device and your changes are gone. On Ubuntu the script can be run in user space. Just add the user to vboxuser. On other linux flavors it may help to add the user to group scanner.

While testing I noticed a weird error code from libusb (v0.1.12). When I made a bulk_write to endpoint 0x03 I always received error code -ENOENT (-2) "no such file or directory". First I thought it's a problem with the device permissions but we are running as root and mode 0644 is okay. And as we are running a perl script there can't be timing problems. It's USB 2.0 so the response is ready in a few µ seconds. Perl needs more time to go to the next usb command than this. And yes I have tested with an additional delay of about 10 ms with no change on the error code. So I simply ignored that error. The next bulk_read from endpoint 0x83 nevertheless brought the correct result.

Let me know your results, if you made a test with your scanner. Every help is highly appreciated.

First results

Scanner protocol is very high level. With a structural analysis it is possible to see functional blocks of driver code.

I managed to figure out the start sequence for scanning and I know how to read the buttons of the scanner.

More details of my analysis can be found in the text file analysis.txt (25.3 kB).

Here is my first successful decoding of scan data. The first picture is what I've calculated. The second picture is what has been saved by vendor software. Yes I know, I'll have to perform some gamma correction. At the moment it's no problem because Gimp can do the job as well.

The scan data is simply returned line by line. First a line with blue colour bytes, then a line with green colour bytes and last a line with red colour bytes. This sequence is repeated until the last scan line. Width is padded to a multiple of 128. You can see it as a black column on the right.

To decode the scan data some preprocessing has to be done.

Script to extract scan data
(you have to give the log filename as parameter. Output is displayed to STDOUT so you'll have to redirect it to a file)
image-get.pl (4.2 kB)

To extract scan data try perl image-get.pl snoop5.txt >image-data5.txt

Extracted scan data (output from image-get.pl)
image-data1.zip (28.9 kB)
image-data2.zip (1.4 MB)
image-data3.zip (1.2 MB)
image-data4.zip (4.3 MB)
image-data5.zip (1.0 MB)

Script to display scan data
(you have to give the previously generated image data file as parameter, second parameter is the width of the image, third parameter is count of lines to skip)
image-show.pl (2.6 kB)

To display the image try
perl image-show.pl [imagefile] [width] [height]
perl image-show.pl image-data5.txt 256 234 1 (german post stamp) or
perl image-show.pl image-data4.txt 1280 37 (O'Reilly perl book) or
perl image-show.pl image-data2.txt 640 234 (blank white page)

The parameters of image-show.pl are:
- first the image data file output from image-get.pl
- second the image width padded to a multiple of 8 (LiDE70: multiple of 16)
- third the amount of lines to skip calibration data
- fourth amount of pixels to skip to roll image horizontally.

There is also an image of the calibration process. Try
perl image-show.pl image-data5.txt 128 0

Script to convert scan data into PNM graphics file
(you have to give the previously generated image data file as parameter, second parameter is the width and the heigth of the image)
image-conv.pl (1.7 kB)

The previous script image-show.pl uses perls Tk package to display a graphics canvas. If you don't want to install this really big package you can use the script image-conv.pl to convert the image data into a PNM graphics file. Then you can view it with Gimp or an ordinary image viewer.

perl image-conv.pl [imagefile] [width] [height]
perl image-conv.pl image-data5.txt 256 234 1 (german post stamp) or
perl image-conv.pl image-data1.txt (default is 128x128 pixels)