sane-project-standard/environment.rst

246 wiersze
11 KiB
ReStructuredText

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

.. _chap:environ:
The SANE Environment
====================
SANE is defined as a C-callable library interface. Accessing a raster
scanner device typically consists of two phases: first, various controls
of the scanner need to be setup or queried. In the second phase, one or
more images are acquired.
Since the device controls are widely different from device to device,
SANE provides a generic interface that makes it easy for a frontend to
give a user access to all controls without having to understand each and
every device control. The design principle used here is to abstract each
device control into a SANE *option*. An option is a self-describing
name/value pair. For example, the brightness control of a camera might
be represented by an option called ``brightness`` whose
value is an integer in the range from 0 to 255.
With self-describing options, a backend need not be concerned with
*presentation* issues: the backend simply provides a list of options
that describe all the controls available in the device. Similarly, there
are benefits to the frontend: it need not be concerned with the
*meaning* of each option. It simply provides means to present and alter
the options defined by the backend.
Attaching to a SANE backend
---------------------------
The process through which a SANE frontend connects to a backend is
platform dependent. Several possibilities exist:
- **Static linking:** A SANE backend may be linked directly into a
frontend. While the simplest method of attaching to a backend, it is
somewhat limited in functionality since the available devices is
limited to the ones for which support has been linked in when the
frontend was built. But even so static linking can be quite useful,
particularly when combined with a backend that can access scanners
via a network. Also, it is possible to support multiple backends
simultaneously by implementing a meta backend that manages several
backends that have been compiled in such a manner that they export
unique function names. For example, a backend called
``be`` would normally export a function called
:func:`sane_read()`. If each backend would provide such a
function, static linking would fail due to multiple conflicting
definitions of the same symbol. This can be resolved by having
backend ``be`` include a header file that has lines
of the form:
::
#define sane_read be_sane_read
With definitions of this kind, backend ``be`` will
export function name ``be_sane_read()``. Thus, all
backends will export unique names. As long as a meta backend knows
about these names, it is possible to combine several backends at link
time and select and use them dynamically at runtime.
- **Dynamic linking:** A simpler yet more powerful way to support
multiple backends is to exploit dynamic linking on platforms that
support it. In this case, a frontend is linked against a shared
library that implements any SANE backend. Since each dynamically
linked backend exports the same set of global symbols (all starting
with the prefix ``sane_``), the dynamic library that
gets loaded at runtime does not necessarily have to be the same one
as one the frontend got linked against. In other words, it is
possible to switch the backend by installing the appropriate backend
dynamic library.
More importantly, dynamic linking makes it easy to implement a meta
backend that loads other backends *on demand*. This is a powerful
mechanism since it allows adding new backends merely by installing a
shared library and updating a configuration file.
- **Network connection:** Arguably the ultimate way to attach to a
scanner is by using the network to connect to a backend on a remote
machine. This makes it possible to scan images from any host in the
universe, as long as there is a network connection to that host and
provided the user is permitted to access that scanner.
.. figure:: figs/hierarchy.*
:name: fig:hierarchy
:scale: 100%
:align: center
Example SANE Hierarchy
The above discussion lists just a few ways for frontends to attach to a
backend. It is of course possible to combine these solutions to provide
an entire hierarchy of SANE backends. Such a hierarchy is depicted in
:numref:`fig:hierarchy`. The figure shows that machine A
uses a dynamic-linking based meta backend called ``dll``
to access the backends called ``pnm``,
``mustek``, and ``net``. The first two
are real backends, whereas the last one is a meta backend that provides
network transparent access to remote scanners. In the figure, machine B
provides non-local access to its scanners through the SANE frontend
called ``saned``. The ``saned`` in turn
has access to the ``hp`` and ``autolum``
backends through another instance of the ``dll``
backend. The ``autolum`` meta backend is used to
automatically adjust the luminance (brightness) of the image data
acquired by the camera backend called ``qcam``.
Note that a meta backend really is both a frontend and a backend at the
same time. It is a frontend from the viewpoint of the backends that it
manages and a backend from the viewpoint of the frontends that access
it. The name “meta backend” was chosen primarily because the SANE
standard describes the interface from the viewpoint of a (real)
frontend.
.. index:: image data format
.. _sec:imageformat:
Image Data Format
-----------------
Arguably the most important aspect of an image acquisition system is how
images are represented. The SANE approach is to define a simple yet
powerful representation that is sufficient for vast majority of
applications and devices. While the representation is simple, the
interface has been defined carefully to allow extending it in the future
without breaking backwards compatibility. Thus, it will be possible to
accommodate future applications or devices that were not anticipated at
the time this standard was created.
A SANE image is a rectangular area. The rectangular area is subdivided
into a number of rows and columns. At the intersection of each row and
column is a quadratic pixel. A pixel consists of one or more sample
values. Each sample value represents one channel (e.g., the red
channel). Each sample value has a certain bit depth. The bit depth is
fixed for the entire image and can be as small as one bit. Valid bit
depths are 1, 8, or 16 bits per sample. If a devices natural bit depth
is something else, it is up to the driver to scale the sample values
appropriately (e.g., a 4 bit sample could be scaled by a factor of four
to represent a sample value of depth 8).
Image Transmission
~~~~~~~~~~~~~~~~~~
The SANE API transmits an image as a sequence of frames. Each frame
covers the same rectangular area as the entire image, but may contain
only a subset of the channels in the final image. For example, a
red/green/blue image could either be transmitted as a single frame that
contains the sample values for all three channels or it could be
transmitted as a sequence of three frames: the first frame containing
the red channel, the second the green channel, and the third the blue
channel.
Conceptually, each frame is transmitted a byte at a time. Each byte may
contain 8 sample values (for an image bit depth of 1), one full sample
value (for an image bit depth of 8), or a partial sample value (for an
image bit depth of 16 or bigger). In the latter case, the bytes of each
sample value are transmitted in the machines native byte order.
For depth 1, the leftmost pixel is stored in the most significant bit,
and the rightmost pixel in the least significant bit.
**Backend Implementation Note**
A network-based meta backend will have to ensure that the byte order
in image data is adjusted appropriately if necessary. For example,
when the meta backend attaches to the server proxy, the proxy may
inform the backend of the servers byte order. The backend can then
apply the adjustment if necessary. In essence, this implements a
“receiver-makes-right” approach.
.. figure:: figs/xfer.*
:name: fig:xfer
:scale: 50%
:align: center
Transfer order of image data bytes
The order in which the sample values in a frame are transmitted is
illustrated in :numref:`fig:xfer`. As can be seen, the
values are transmitted row by row and each row is transmitted from
left-most to right-most column. The left-to-right, top-to-bottom
transmission order applies when the image is viewed in its normal
orientation (as it would be displayed on a screen, for example).
If a frame contains multiple channels, then the channels are transmitted
in an interleaved fashion. :numref:`fig:pixels`
illustrates this for the case where a frame contains a complete
red/green/blue image with a bit-depth of 8. For a bit depth of 1, each
byte contains 8 sample values of a *single* channel. In other words, a
bit depth 1 frame is transmitted in a byte interleaved fashion.
.. figure:: figs/image-data.*
:name: fig:pixels
:scale: 80%
:align: center
Bit and byte order of image data
When transmitting an image frame by frame, the frontend needs to know
what part of the image a frame represents (and how many frames it should
expect). For that purpose, the SANE API tags every frame with a type.
This version of the SANE standard supports the following frame types:
:macro:`SANE_FRAME_GRAY`:
The frame contains a single channel of data that represents
sample values from a spectral band that covers the human visual
range. The image consists of this frame only.
:macro:`SANE_FRAME_RGB`:
The frame contains three channels of data that represent sample
values from the red, green, and blue spectral bands. The sample
values are interleaved in the order red, green, and blue. The
image consists of this frame only.
:macro:`SANE_FRAME_RED`:
The frame contains one channel of data that represents sample
values from the red spectral band. The complete image consists
of three frames: :macro:`SANE_FRAME_RED`,
:macro:`SANE_FRAME_GREEN`, and
:macro:`SANE_FRAME_BLUE`. The order in which the
frames are transmitted chosen by the backend.
:macro:`SANE_FRAME_GREEN`:
The frame contains one channel of data that represents sample
values from the green spectral band. The complete image consists
of three frames: :macro:`SANE_FRAME_RED`,
:macro:`SANE_FRAME_GREEN`, and
:macro:`SANE_FRAME_BLUE`. The order in which the
frames are transmitted chosen by the backend.
:macro:`SANE_FRAME_BLUE`:
The frame contains one channel of data that represents sample
values from the blue spectral band. The complete image consists
of three frames: :macro:`SANE_FRAME_RED`,
:macro:`SANE_FRAME_GREEN`, and
:macro:`SANE_FRAME_BLUE`. The order in which the
frames are transmitted chosen by the backend.
In frames of type :macro:`SANE_FRAME_GRAY`, when the bit depth is 1 there are
only two sample values possible, 1 represents minimum intensity
(black) and 0 represents maximum intensity (white). For all other bit
depth and frame type combinations, a sample value of 0 represents
minimum intensity and larger values represent increasing intensity.
The combination of bit depth 1 and :macro:`SANE_FRAME_RGB` (or
:macro:`SANE_FRAME_RED`, :macro:`SANE_FRAME_GREEN`, :macro:`SANE_FRAME_BLUE`)
is rarely used and may not be supported by every frontend.