sane-project-website/sane2/0.08/doc013.html

208 wiersze
8.8 KiB
HTML

<html><body>
<a href="doc014.html"><img src=../icons/next.gif alt="Next"></a>
<a href="doc000.html"><img src=../icons/up.gif alt="Up"></a>
<a href="doc012.html"><img src=../icons/previous.gif alt="Previous"></a>
<a href="doc000.html"><img src=../icons/contents.gif alt="Contents"></a>
<a href="doc019.html"><img src=../icons/index.gif alt="Index"></a>
<hr>
<title>Code Flow</title>
<h2><a name="s4.4">4.4 Code Flow</a></h2><a name="i117">
<p>The code flow for the SANE API is illustrated in
Figure <a href="doc013.html#f4">4</a>. Functions <tt>sane_init()</tt> and
<tt>sane_exit()</tt> initialize and exit the backend, respectively.
All other calls must be performed after initialization and before
exiting the backend.
<p><p><a name="f4"></a>
<center>
<img width=566 height=510 src="img003.gif">
<p><center>Figure 4: Code flow</center>
</center>
<p>
<p>Function <tt>sane_get_devices()</tt> can be called any time after
<tt>sane_init()</tt> has been called. It returns the list of the
devices that are known at the time of the call. This list may change
over time since some devices may be turned on or off or a remote host
may boot or shutdown between different calls. It should be noted that
this operation may be relatively slow since it requires contacting all
configured devices (some of which may be on remote hosts). A frontend
may therefore want to provide the ability for a user to directly
select a desired device without requiring a call to this function.
<p>Once a device has been chosen, it is opened using a call to
<tt>sane_open()</tt>. Multiple devices can be open at any given time.
A SANE backend must not impose artificial constraints on how many
devices can be open at any given time.
<p>An opened device can be setup through the corresponding device handle
using functions <tt>sane_get_option_descriptor()</tt> and
<tt>sane_control_option()</tt>. While setting up a device, obtaining
option descriptors and setting and reading of option values can be
mixed freely. It is typical for a frontend to read out all available
options at the beginning and then build a dialog (either graphical or
a command-line oriented option list) that allows to control the
available options. It should be noted that the number of options is
fixed for a given handle.
<font color="darkgreen">
However, as options are set, other options may become active or inactive or
their constraint may change. Thus, after setting an option, it may be
necessary to re-read the descriptors.
</font>
While
setting up the device, it is also admissible to call
<tt>sane_get_parameters()</tt> to get an estimate of what the image
parameters will look like once image acquisition begins.
<p>The device handle can be put in blocking or non-blocking mode by a
call to <tt>sane_set_io_mode()</tt>. Devices are required to support
blocking mode (which is the default mode), but support for
non-blocking I/O is strongly encouraged for operating systems such as
UNIX.
<p>After the device is setup properly, image acquisition can be started
by a call to <tt>sane_start()</tt>. The backend calculates the exact
image parameters at this point. So future calls to
<tt>sane_get_parameters()</tt> will return the exact values, rather
than estimates. Whether the physical image acquisition starts at this
point or during the first call to <tt>sane_read()</tt> is unspecified
by the SANE API. If non-blocking I/O and/or a select-style interface
is desired, the frontend may attempt to call
<tt>sane_set_io_mode()</tt> and/or <tt>sane_get_select_fd()</tt> at
this point. Either of these functions may fail if the backend does
not support the requested operation.
<p><font color="darkgreen">
Image data is collected by repeatedly calling <tt>sane_read()</tt>
until this function will return an end-of-file status
(<tt>SANE_STATUS_EOF</tt>). This indicates the end of the current
frame. If the frontend expects additional frames (e.g., the
individual channels of a red/green/blue image or multiple images),
it can call <tt>sane_start()</tt> again.
If the <tt>SANE_PFLAG_LAST_FRAME</tt> bit is set in <tt>flags</tt>, the
current image is complete. In this case, it should be tested, if
<tt>flags</tt> has the <tt>SANE_PFLAG_MORE_IMAGES</tt> bit set.
If yes, further calls to <tt>sane_start()</tt> can be made to acquire
more images. Please note, that as this bit has to be set at the beginning
of a the transmission of the last frame before the new image, it is possible,
that no reliable decision can be made at this time. It is thus permissible
for a backend to set this bit, and then later at the actual call to
<tt>sane_start()</tt> return an error like <tt>SANE_STATUS_NO_DOCS</tt>.
Such a sequence is permitted to transmit multiple images from a single
page as well as multiple pages. This behaviour should be controlled by
backend options as required, to allow single-page scanning as well as
ADF-batch-scanning. The frontend should always continue reading all images
until a frame with <tt>SANE_PFLAG_LAST_FRAME</tt> on
and <tt>SANE_PFLAG_MORE_IMAGES</tt> off is encountered, or an error other
than <tt>SANE_STATUS_EOF</tt> occurs in a SANE function.
Note that <tt>SANE_STATUS_NO_DOCS</tt> also is an allowed way for the backend
to indicate the end of a multiple image scan.
<p>A frontend may choose to skip frames (e.g. because it cannot parse them),
which is accomplished by simply calling <tt>sane_start</tt> again, which will get
you to the next frame, without having to read and discard the current one.
<p>In order to prematurely stop scanning and to reset the backend state,
<tt>sane_cancel()</tt> can be called at any time. This call is required
as well after normal termination of a multiple image scan as described above.
</font>
<p>When done using the device, the handle should be closed by a call to
<tt>sane_close()</tt>. Finally, before exiting the application,
function <tt>sane_exit()</tt> must be called. It is important not to
forget to call this function since otherwise some resources (e.g.,
temporary files or locks) may remain unclaimed.
<p><font color="darkgreen">
The following C sample code implements a reference loop for acquiring
multiple images:
<p><pre>
SANE_Parameters parms;
SANE_Status status;
do
{
do
{
/* Now start acquiring the next frame. */
status = sane_start (handle);
/* if that failed, we have a problem, and no more frames can be
* read at this time. Due to SANE_PFLAG_MORE_IMAGES still
* being clear, this will break out of _BOTH_ loops.
*/
if (status != SANE_STATUS_GOOD)
break;
/* Now let us see what the next frame brings. */
status = sane_get_parameters (handle, &amp;parms);
/* This actually should not fail, but maybe the doc feeder
* jammed or something, so we break as well, if something
* is wrong.
*/
if (status != SANE_STATUS_GOOD)
break;
/* Now we check the announced parameters, if we can make use
* of the frame data. If not, we skip over to the next frame.
*/
if (do_i_like_that (&amp;parms) == NO)
continue;
/* Set up for reading the data here. Mangle filenames,
* allocate memory, rewind multiframe files, ask user
* for confirmation, ...
*/
setup_for_transfer (...);
/* Now we read in the frame data and process it. This should
* return SANE_STATUS_GOOD, until the frame is complete,
* what causes SANE_STATUS_EOF to be returned.
*/
while (SANE_STATUS_GOOD == (status = sane_read (...)))
read_in_and_process_data_as_required ();
/* If transfer was broken due to anything but EOF, break out. */
if (status != SANE_STATUS_EOF)
break;
/* Now loop until we have all frames of an image. */
}
while (!(parms.flag &amp; SANE_PFLAG_LAST_FRAME));
/* O.K. - we now have a complete image. Fit it together, save it,
* flush buffers, transmit it, increment filenames, etc.
*/
/* Now check for more pending images. If we have more, redo from start.
* Some backends might cheat here and send us for an extra round which
* will fail at sane_start, as they were not able to determine if they
* would have more data at the start of the last frame we read.
*/
}
while (parms.flags &amp; SANE_PFLAG_MORE_IMAGES);
/* No more data. Fine. Reset the backend and go back to option-control
* loop.
*/
sane_cancel (handle);
</pre>
<p></font>
<p><p><hr>
<a href="doc014.html"><img src=../icons/next.gif alt="Next"></a>
<a href="doc000.html"><img src=../icons/up.gif alt="Up"></a>
<a href="doc012.html"><img src=../icons/previous.gif alt="Previous"></a>
<a href="doc000.html"><img src=../icons/contents.gif alt="Contents"></a>
<a href="doc019.html"><img src=../icons/index.gif alt="Index"></a>
<hr>
</body></html>