scx-xx: Samsung SCX-4200 Scanner GPL driver
NOTE: This device is currently supported by xerox_mfp
SANE driver; please use it instead. For list of compatible devices see
SANE support of Samsung devices page.
This page is a result of my attempt to create open driver for Samsung
SCX-4200 MFP Scanner. No information from Samsung was available, this
driver is based only on usb traffic created by Samsung's Linux binary driver
for this scanner.
LEGAL NOTE:
THIS SOFTWARE COMES WITH ABSOLUTELY NO WARRANTY! USE AT YOUR OWN RISK!
LICENSE:
This is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License version 2 as published by the Free
Software Foundation. It is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
Introduction
SCX-4200 is a laser MFP with CIS flatbed scanner. Samsung offers a Linux driver
for both the printer part as well as scanner part, but only in binary form.
It is possible that more devices might use the same protocol - these ones
seem to be supported by Samsung's driver (based on smfp.conf file):
- id="sf531p" modelstring="APOLLO"
- id="scx5312f" modelstring="ORION"
- id="mfp560" modelstring="MFP 560 Series"
- id="mfp750" modelstring="MFP 750 Series"
- id="scx4100" modelstring="SCX-4100 Series"
- id="scx4200" modelstring="SCX-4200 Series"
- id="scx4x16" modelstring="SCX-4x16 Series"
- id="scx4x20" modelstring="SCX-4x20 Series"
- id="scx5x30" modelstring="SCX-5x30 Series"
- id="clx3160" modelstring="CLX-3160 Series"
- id="scx4x21" modelstring="SCX-4x21 Series"
- id="scx4725" modelstring="SCX-4725 Series"
- id="scx6x20" modelstring="SCX-6x20 Series"
However, this needs to be checked first.
Current status: preAlpha - developers only
So far, the only device tested is SCX-4200, which works fine.
NOTE: There is no user-friendly interface so far (only a trivial command line).
The output is written to stdout as raw data without any headers; actual
image resoultion is written to stderr. You can either prepend PNM headers, or
open it with GIMP and specify correct parameters there.
What you need to test it
SCX-4200 is USB-only device, and it is accessed using its printer interface -
that is, /dev/usb/lp0 (this is hardcoded, so if you have it somewhere else, you have to
change it first). You need kernel support for USB printers
(module usblp on 2.6.x kernels) - should be included in any recent distro
you can find these days. I don't know anything about connecting Parallel port
scanners - but I would expect they use their printer interface directly as well.
Download
Protocol description
All commands sent to the scanner are 4 bytes long, except for scanning
configuration which is longer. Most responses from scanner are 32 bytes long,
except for DeviceInfo which is longer (and raw data, which are not considered
as responses); however actual response length is stored in the response so
we don't rely on this.
Commands identified so far:
- DeviceInfo - [1b a8 12 00]
Request device information and capabilities.
- StartConfig - [1b a8 16 00]
This one needs to be sent before configuring the scan area etc.; otherwise
scanner rejects any configuration.
- Config -
[1b a8 24 13 30
00 00 12 45
00 00 05 5a
05 05
01 12
07 08
03
00 00 02 40 00]
Configure scanner. All parameters are set within this message - scanning area,
resolution and color depth.
There are 8 parts:
- Header, 5 bytes
- Scan width, 4 bytes
- Scan height, 4 bytes
- Resolution, 2 bytes (probably 1 byte for Xres and 1 for Yres since these 2 are always the same)
- Left offset, 2 bytes
- Top offset, 2 bytes
- Color mode, 1 byte
- Something, 5 bytes
Encoding of scan width and height:
Let V be value in mm, then width/height (X) is calculated as follows:
X = ceil( V/25.4 * 1200 - 47 )
(don't ask me about that 47) Value is stored in big-endian format.
Encoding of resolution:
- [00 00] = 75dpi
- [0a 0a] = 100dpi
- [02 02] = 150dpi
- [09 09] = 200dpi
- [05 05] = 300dpi
- [07 07] = 600dpi
Encoding of left/top offset:
Let V be value in mm, then left/top (X) is calculated as follows:
X = floor( V/25.4 * 100 )
However, this value is not stored directly, but as two bytes - [X/100] and [X%100].
Encoding of color mode:
- [00] = Black&White - LineArt
- [01] = Black&White - Halftone
- [03] = Grayscale (8bpp)
- [05] = Truecolor (24bpp)
- Start - [1b a8 31 00]
Start scanning operation.
- Stop - [1b a8 06 00]
Stop scanning operation.
- Status - [1b a8 28 00]
This has to be sent periodically to query if there are some data to transfer.
- SendData - [1b a8 29 00]
When Status response indicates that there are some data, this command
instructs the scanner to send its buffer (up to 1MB for SCX-4200).
- Something - [1b a8 17 00]
Something, usually sent after Stop (probably somehow related
to opening StartConfig). Currently scx-xx doesn't emit this command.
Responses identified so far:
- [a8001d00 00000000 00000000 00000000 00000000 00000000 00000000 00000000] - OK
- [a8001d00 00000000 00000001 00000001 00000000 00000000 00000000 00000000] - OK
- [a8021d20 ........ ........ ........ ........ ........ ........ ........] - Error
- [a8081d80 00000010 000000ff 00010000 00000000 00000000 00000000 00000000] - No Data
- [a8001d81 0000d420 00570270 00010000 00000000 00000000 00000000 00000000] - Data, not last chunk
- [a8001d80 0000d420 00570270 00010000 00000000 00000000 00000000 00000000] - Data, last chunk
- [a8004310 53414d53 554e4720 4f52494f 4e202020 20202020 20202020 20202020 20202020 353f0429
000027d8 000036d8 00012f00 00020000 000036d8 000036d8 010b0505 0000] - Device Info
Currently, responses are identified only by bytes 2 and 4, its length (minus 3) is in byte 3.
As you can see above, there can be some flags encoded further in the message...
Data ... responses: bytes 5-8 contain length of data that are ready to
be sent to host, bytes 9-10 contain pixel width of this chunk, bytes 11-12 then
pixel height of this chunk. Last bit of 4th byte indicates last chunk of data to
be transferred.
In the Device Info response, plaintext "SAMSUNG ORION" can be seen.
In addition, value 000027d8 is about 215.9mm for 1200dpi and
value 000036d8 is about 297.18mm for 1200dpi - probably physical scannable
area. Other fields are not known yet (and those that are are not used either).
Format of scan data:
Image data are transferred without any compression or special encoding, row-by-row:
- 1bpp modes - 8 pixels are packed into 1 byte
- 8bpp Grayscale mode - pixel per byte
- 24bpp Color mode - some trivial processing is needed here. First, red row is transferred,
then green row, and finally blue row. This has to be converted to usual rgb tripple.
(Actually, if you know how CIS scanners work, this is a natural way how to transfer rgb data.)
There are 16 more bytes appended to the end of each chunk; we just discard them.
Sample session
- send DeviceInfo command
--> DeviceInfo response will be sent
- send StartConfig command
--> OK response will be sent
- send Config command
--> OK response will be sent
- send Start command
--> OK response and No Data response will be sent
- while not done:
- sleep a while
- send Status command
--> No Data response - do nothing
--> Data, not last chunk:
- send SendData command
- read all image chunk data
--> Data, last chunk:
- send SendData command
- read all image data
- break
end while
- send Stop command
--> OK response will be sent
Issues
- Image size
It is not clear how big the image will be before we fetch all its chunks.
Image width is clear from first received chunk, however we don't know full
height. The problem is that you will get different height for exactly the same
scanning area, but different color mode. An example:
- Truecolor - 4x[1644x186], 1x[1644x34]. Total height: 778 pixels
- Grayscale - 1x[1644x558], 1x[1644x218]. Total height: 776 pixels
- Black&White - 1x[216x776]. Total height: 776 pixels
(The width can be different for BW modes, but we know that with first chunk.)
This needs to be solved; I'm afraid that Samsung's binary driver does save raw
data to /tmp first and then creates another image in /tmp with headers.
Also Sane wants to know exact pixel size before it reads actual image data.
(A4 in color means about 100MB of raw data that we need to store)
Contact
vlado {at} sane {dot} ksp {dot} sk