Re: SANE frames

Tom Martone (tom@martoneconsulting.com)
Sun, 15 Aug 1999 15:29:36 -0400

Stephen Williams wrote:
>
> oliver.rauch@Wolfsburg.DE said:
> > May be we should add a generic n-channel frame format
> > (SANE_FRAME_N_CHANNELS or dthg like that) and put the numbers of
> > frames and a list with the name/types of the frames into the parameter
> > block.
>
> This reminds me. Some of the scanners I'm working on not only generate
> compressed images, but can have multiple images per page. I'm thinking
> for example of one document scanner that can, for each page, produce
> all at once:
>
> up to 8 color images
> up to 8 gray images
> up to 8 binary images
>
> Not to mention backside images as well. Each image can have different
> characteristics (i.e. JFIF color/gray, TIFF G4 binary) and dimensions.
> In particular, the scanner supports windows with these different properties
> and their own scan area. An aware application needs to be able to find
> out that these images are from the same page. Ideas?
Perhaps the backend could set an option value (SANE_CAP_SOFT_DETECT)
that specifies the number of images per scan operation? In my usage,
since it is batch aquisition, I rely on an external process to "paginate"
the images. The user is actually knowledgeable about how many images
per pages scanned will be delivered, because they are specifying the
options (duplex, multiple sections, etc) This is limiting, though.

Another thing that's pretty typical is using batchcode or patchcodes
to separate multiple page documents. I've not really gotten to far
into that issue, however. Again, I was thinking that an external
process would handle that one as well, as long as I could get the
decoded bar/patchcode data through SANE.

But just getting the multiple images per physical scan operation through
SANE is an issue as well. Just like in your scanner example, Bell+Howell
supports 8 scanning windows as well as the full scan area and a user-
sizeable thumbnail (or icon). Duplex models support this on both sides
of the pages, so you can get up to 20 images for each page that goes
through the scanner.

1 Full Front Page
1 Front Page Thumbnail (Icon)
8 User-Defined Front Page Sections (scan areas)
1 Full Back Page
1 Back Page Thumbnail (Icon)
8 User-Defined Back Page Sections (scan areas)

The thumbnails cannot be compressed, but the other images can be. They
must all use the same compression setting however, if I remember correctly.

Then if you add in the barcode/patchcode feature you get an additional
18 more items per side, potentially. But I was thinking of consolidating
all of that into a single xml-encoded text stream. Any ideas on this one?

The multiple images per physical scan operation can be handled by
a judicious calling of sane_cancel by the frontend. This gives the
backend a clue as to whether to return subsequent images from the latest
physical scan operation, or to drop them and actually scan the next page.

I posted a message regarding my method for supporting this a while back.
I'll repeat it here. If you look at Section 4.4 Code Flow there's a
diagram which shows the sequence of calls that a front-end should make
and a paragraph which specifically mentions when sane_cancel must be
called. Here it is:

Image data is collected by repeatedly calling sane_read(). Eventually,
this function will return an end-of-file status (SANE_STATUS_EOF).
This indicates the end of the current frame. If the frontend expects
additional frames (e.g., the individual channels in of a red/green/blue
image or multiple images), it can call sane_start() again. Once all
desired frames have been acquired, function sane_cancel() must be
called. This operation can also be called at any other time to cancel
a pending operation. Note that sane_cancel() must be called even if
the last read operation returned SANE_STATUS_EOF.

Now here are traces of scanadf and xsane 0.31 calling the Bell+Howell
backend with the feeder loaded with 3 pages and a duplex scan requested.
The goal of course is to acquire 6 images: 3 fronts and 3 backs.

>From scanadf.adf.duplex.log

[bh] sane_init called
[bh] sane_open called
[bh] sane_control_option called (option:0, action:0)...
[bh] sane_get_option_descriptor called (option:0)...
[bh] sane_start called
[bh] sane_get_parameters called
[bh] sane_read called...
[bh] sane_start called
[bh] sane_get_parameters called
[bh] sane_read called...
[bh] sane_start called
[bh] sane_get_parameters called
[bh] sane_read called...
[bh] sane_start called
[bh] sane_get_parameters called
[bh] sane_read called...
[bh] sane_start called
[bh] sane_get_parameters called
[bh] sane_read called...
[bh] sane_start called
[bh] sane_get_parameters called
[bh] sane_read called...
[bh] sane_start called (returns SANE_STATUS_NO_DOCS)
[bh] sane_cancel called
[bh] sane_close called
[bh] sane_exit called

>From xsane.adf.duplex.log

[bh] sane_init called
[bh] sane_get_devices called
[bh] sane_open called
[bh] sane_control_option called (option:0, action:0)...
[bh] sane_get_option_descriptor called (option:1)...
* [bh] sane_get_parameters called
[bh] sane_start called
[bh] sane_get_parameters called
[bh] sane_set_io_mode called: non_blocking=1
[bh] sane_read called...
[bh] sane_get_option_descriptor called...
[bh] sane_cancel called
* [bh] sane_get_parameters called
[bh] sane_get_option_descriptor called (option:0)...
[bh] sane_start called
[bh] sane_get_parameters called
[bh] sane_set_io_mode called: non_blocking=1
[bh] sane_read called...
[bh] sane_get_option_descriptor called (option:0)...
[bh] sane_cancel called
* [bh] sane_get_parameters called
[bh] sane_get_option_descriptor called (option:0)...
[bh] sane_start called
[bh] sane_get_parameters called
[bh] sane_set_io_mode called: non_blocking=1
[bh] sane_read called...
[bh] sane_get_option_descriptor called (option:0)...
[bh] sane_cancel called
* [bh] sane_get_parameters called
[bh] sane_get_option_descriptor called (option:0)...
[bh] sane_start called
[bh] sane_get_option_descriptor called (option:0)...
[bh] sane_close called
[bh] sane_exit called

The resulting behavior is that scanadf gets 6 images and xsane gets
3 images. The reason is that each frontend has a different idea on
when sane_cancel must be called. Oliver tells me that the scanadf
behavior is not conforming to the standard; I don't share that view
and would welcome others to comment.

Assuming for a moment that scanadf is indeed proper, then the aquisition
of each and every image produced by the Bell+Howell per physical page
can be passed through to the front end, exactly as in this duplex
scenario. So on this issue, I think we're very close to having a
officially sanctioned standard solution. Perhaps, this could be added
to the paragraph above to alert frontend writers to the subtleties of
the sane_cancel call.

If a frontend is performing a multiple image aquisition operation
(e.g., acquiring images from a duplex scanner, or a scanner with
section support, acquiring images from a scanner equipped with an
automatic document feeder), the frontend should call sane_cancel once
only after all images have been acquired. This allows a backend a hint
as to the duration of the batch and provides an opportunity for the
backend to perform batch related optimizations or deliver multiple
images from a single physical scan operation.

Related to the above is the special "batch mode" supported by the
Bell+Howell. In this mode the scanner is actually ahead of the host
in terms of feeding in paper and scanning. It buffers the image data
in its own memory and the hardware compression and barcode decoding
are taking place simultaneously with the scanning of the subsequent
image. The Bell+Howell backend, when the batch option is turned on,
starts batch mode prior to the first START SCAN and terminates the
batch mode when sane_cancel is called. This works real nice.

>
> This is not so pressing to me as the application being able to select
> compressed frame formats (and blocking formats it can't handle) but
> someone should be thinking of these things.
>
> I know, I'm a pest on this list:-)
I don't think you are a pest. Rather, it seems that a lot of the focus
is on interactive, high-depth color scanning, while some of us are working
in a quite different niche, that of high-volume, low-resolution, bilevel
or grayscale scanning. In this arena, there are different problems to
solve. I'm glad you're active in this area; it gives me the confidence
that we can work together and make a bunch of progress in this area.

It think we share the following issues:
1) image compression, which involves adding SANE frame formats.
2) duplex scanning/multiple scan windows
3) feeder support/batch operation/performance issues
4) barcode/patchcode support, perhaps also tied to SANE frame formats,
but even stranger because the data is not an image at all.

If I missed some, please add them.

I think all of these are addressable without a great deal of alteration
to the SANE standard. In fact, I have a workable solution for my needs
at the moment. I'd really like to integrate this all back in and get
blessing, etc. I'd also like to be able to use some of the esoteric
functions of the Bell+Howell backend with Xsane. Oliver recently added
ADF support to version 0.31 of Xsane which works fine with the Bell+
Howell, but the multiple images per physical scan issue not being supported
reduces its usefulness. Currently, each of the 4 options above do not
work with arbitrary frontends. I see that as a necessary hurdle to jump
over, and incorporating these features into the standard is the right
way to go.

To that end, I'm preparing to address issues 1 and 4 in a following email.

I think number 2 is pretty well outlined by both of us here, and hopefully
we'll get some feedback regarding the conformance concerns.

I think number 3 boils down to either a totally new frontend for high
volume document scanning, or significant enhancements to scanimage.

Tom Martone

--
Source code, list archive, and docs: http://www.mostang.com/sane/
To unsubscribe: echo unsubscribe sane-devel | mail majordomo@mostang.com