## 4.5 Well-Known Options

While most backend options are completely self-describing, there are cases where a user interface might want to special-case the handling of certain options. For example, the scan area is typically defined by four options that specify the top-left and bottom-right corners of the area. With a graphical user interface, it would be tedious to force the user to type in these four numbers. Instead, most such interfaces will want to present to the user a preview (low-resolution scan of the full scanner surface or a high(er) resolution scan of a subpart of the scanner surface) and let the user pick the scan area by dragging a rectangle into the desired position. For this reason, the SANE API specifies a small number of option names that have well-defined meanings.

### 4.5.1 Option Number Count

Option number 0 has an empty string as its name. The value of this option is of type `SANE_TYPE_INT` and it specifies the total number of options available for a given device (the count includes option number 0). This means that there are two ways of counting the number of options available: a frontend can either cycle through all option numbers starting at one until `sane_get_option_descriptor()` returns `NULL`, or a frontend can directly read out the value of option number 0.

### 4.5.2 Scan Resolution Options

Option `resolution` is used to select the resolution at which an image should be acquired. When the backend wants to allow different values for x- and y-resolution it has to define the options `x_resolution` and `y_resolution`. Note that only the option `resolution` or the options `x_resolution` and `y_resolution` may be active.

The type of this option is either `SANE_TYPE_INT` or `SANE_TYPE_FIXED`. The unit is `SANE_UNIT_DPI` (dots/inch).

This option is not mandatory, but if a backend does support it, it must implement it in a manner consistent with the above definition.

### 4.5.3 Preview Mode Option

The boolean option `preview` is used by a frontend to inform the backend when image acquisition should be optimized for speed, rather than quality (``preview mode''). When set to `SANE_TRUE`, preview mode is in effect, when set to `SANE_FALSE` image acquisition should proceed in normal quality mode. The setting of this option must not affect any other option. That is, as far as the other options are concerned, the preview mode is completely side effect free. A backend can assume that the frontend will take care of appropriately setting the scan resolution for preview mode (through option `resolution`). A backend is free to override the `resolution` value with its own choice for preview mode, but it is advised to leave this choice to the frontend wherever possible. When the `preview` option is set the backend should transfer the image in frame type `SANE_FRAME_RAW` if possible.

This option is not mandatory, but if a backend does support it, it must implement it in a manner consistent with the above definition.

### 4.5.4 Scan Area Options

The four most important well-known options are the ones that define the scan area. The scan area is defined by two points (x/y coordinate pairs) that specify the top-left and the bottom-right corners. This is illustrated in Figure 5. Note that the origin of the coordinate system is at the top-left corner of the scan surface as seen by the sensor (which typically is a mirror image of the scan surface seen by the user). For this reason, the top-left corner is the corner for which the abscissa and ordinate values are simultaneously the smallest and the bottom-right corner is the corner for which the abscissa and ordinate values are simulatenously the largest. If this coordinate system is not natural for a given device, it is the job of the backend to perform the necessary conversions.

Figure 5: Scan area options

The names of the four options that define the scan area are given in the table below:

Name | Description
`tl-x` | Top-left x coordinate value
`tl-y` | Top-left y coordinate value
`br-x` | Bottom-right x coordinate value
`br-y` | Bottom-right y coordinate value

There are several rules that should be followed by front and backends regarding these options:

- Backends must attach a unit of either pixels (`SANE_UNIT_PIXEL`) or millimeters (`SANE_UNIT_MM`) to these options. The unit of all four options must be identical.

- Whenever meaningful, a backend should attach a range or a word-list constraint to these options.

- A frontend can determine the size of the scan surface by first checking that the options have range constraints associated. If a range or word-list constraints exist, the frontend can take the minimum and maximum values of one of the x and y option range-constraints to determine the scan surface size.

- A frontend must work properly with any or all of these options missing.
- A frontend may temporarily set the values in a way that `tl-x` is larger than `br-x` and `tl-y` is larger than `br-y`.

### 4.5.5 Depth option

Option `depth` is used to select the image depth in bits/sample in multi bit mode - (this means for 24 bit RGB mode this value must be 8). The type of this option is `SANE_TYPE_INT`. The unit is `SANE_UNIT_BIT`. For 1 bit modes (Lineart or Halftone) this option has to be inactive. For selection of 1 bit modes (Lineart or Halftone) the backend should use the well-known option `mode`.
This option is not mandatory, but if a backend does support it, it must implement it in a manner consistent with the above definition.

### 4.5.6 Gamma table options

The `gamma-table` option defines a `SANE_CONSTRAINT_RANGE` of the type `SANE_TYPE_INT` which represents the gamma correction table for gray. In color mode the `gamma-table` may be used to set a common gamma correction for red, green and blue. The options `red-gamma-table`, `green-gamma-table` and `blue-gamma-table` are used in color mode to set a gamma correction for each color separately. In color mode the backend is free to use only the `gamma-table` option, only the `red-`, `green-` and `blue-gamma-table` or all four options. When all four options are used then the color tables should do a gamma correction with the same input and output bit depth and the gray gamma table should reduce (if necessary) the bit depth from the scanner internal bit depth to the output bit depth. This should e.g. look like this:

    red_value   = gamma-table(red-gamma-table(value))
    green_value = gamma-table(green-gamma-table(value))
    blue_value  = gamma-table(blue-gamma-table(value))

The backend should not use the gamma tables to emulate other functions or options like highlight, shadow, contrast, brightness, threshold, analog_gamma. These functions are common for all backends and should be added to the frontend or a meta-backend.
This option is not mandatory, but if a backend does support it, it must implement it in a manner consistent with the above definition.

### 4.5.7 Scan Mode options

The option `mode` defines a `SANE_CONSTRAINT_STRING_LIST` of type `SANE_TYPE_STRING`. It is used to select the scanmode (e.g. Color or Gray). Well known modes are: `Color`, `Gray`, `Halftone` and `Lineart`. `Color` and `Gray` are multi bit modes (8 or 16 bits/sample), `Halftone` and `Lineart` are single bit modes.
This way a frontend can select e.g the mode `Gray` for scanning a fax.
This option is not mandatory, but if a backend does support it, it must implement it in a manner consistent with the above definition.

### 4.5.8 Scan Source options

The option `source` is used to select the scan source (e.g. Automatic Document Feeder). It defines a `SANE_CONSTRAINT_STRING_LIST` of type `SANE_TYPE_STRING`. Well known sources are: `Flatbed`, `Transparancy Adapter` and `Automatic Document Feeder`.
This option is not mandatory, but if a backend does support it, it must implement it in a manner consistent with the above definition.

### 4.5.9 Threshold

The option `threshold` is used to define the threshold for Lineart and maybe Halftone mode. In multi bit modes this option should be set inactive. The type of this option is `SANE_TYPE_FIXED`. The unit is `SANE_UNIT_PERCENT`. The value range should be 0.0...100.0 if possible. It defines the minimum intensity to get a white point / full intensity (image data bit = 0). The backend has to scale the values in the following way:
A value of 0.0 means all pixels get white /full intensity (all image data bits are 0). A value of 50.0 means intensities brighter than medium gray get white / full intensity (bit 0). A value of 100.0 means all pixels get black (all image data bits are 1). If the scanner is not able to cover the full range the backend has to define a reduced value range (e.g. 30...70 percent).

This option is not mandatory, but if a backend does support it, it must implement it in a manner consistent with the above definition.

### 4.5.10 Analog gamma

The option `analog-gamma` is used to define the gamma value for an analog gamma function of the scanner in multi bit modes. In 1 bit modes this option should be set inactive. The type of this option is `SANE_TYPE_FIXED`. The unit is `SANE_UNIT_NONE`. The value range can be defined by the backend as supported. The values have to be positive. A gamma value of 1.0 means that the gamma correction has no effect. A value larger than 1.0 increases the brightness of the image. In color mode there also can be options `analog-gamma-red`, `analog-gamma-green` and `analog-gamma-blue`. It is not allowed to emulate an analog gamma function by a digital gamma table. The backend has to disable (or not define) this option when the scanner does not support an analog (hardware) gamma function.

When analog gamma, highlight and shadow functions are available at the same time then the backend author has to care about the order in which the functions are implemented in the scanner hardware. The SANE standard expects that changing the analog gamma value has no effect on the shadow and highlight function. When the analog gamma function is executed in the scanner hardware before the shadow and highlight functions then the backend should do a compensation. For this the shadow and highlight values have to be gamma corrected with the relevant analog gamma value.

This option is not mandatory, but if a backend does support it, it must implement it in a manner consistent with the above definition.

### 4.5.11 Shadow

The option `shadow` is used to define the shadow level / black point level. The type of this option is `SANE_TYPE_FIXED`. The unit is `SANE_UNIT_PERCENT`. The value range should be 0.0...100.0 if possible. It is used to define the maximum intensity level that creates an image data value of 0 (black). The backend has to scale the values in the following way:
A value of 0.0 means that the sensitivity range is not reduced, only the minimum intensity produces an image data value of 0 (black). A value of 50.0 means that that a medium intensity and everything that is darker produces an image data value of 0 (black). A value of 100.0 means the sensitivity range is reduced to 0, all image data values are 0 (black). If the scanner is not able to cover the full range the backend has to define a reduced value range (e.g. 30...70 percent). In color mode there can be options `shadow-red`, `shadow-green` and `shadow-blue`, in this case the `shadow` function has to be disabled. It is not allowed to emulate a shadow function by a digital gamma table. The backend has to disable (or not define) this option when the scanner does not support an analog (hardware) shadow function.

This option is not mandatory, but if a backend does support it, it must implement it in a manner consistent with the above definition.

### 4.5.12 Highlight

The option `highlight` is used to define the highlight level / white point level. The type of this option is `SANE_TYPE_FIXED`. The unit is `SANE_UNIT_PERCENT`. The value range should be 0.0...100.0 if possible. It is used to define the minimum intensity level that creates the maximum possible image data value (white/full intensity). The backend has to scale the values in the following way:
A value of 0.0 means the sensitivity range is reduced to 0, all image data have maximum value (white / full intensity). A value of 50.0 means that a medium intensity and everything that is brighter produces the maximum possible image data value (white / full intensity). A value of 100.0 means that the sensitivity range is not reduced, only the maximum intensity produces an image data with maximum possible value (white / full intensity). If the scanner is not able to cover the full range the backend has to define a reduced value range (e.g. 30...70 percent). In color mode there can be options `highlight-red`, `highlight-green` and `highlight-blue`, in this case `highlight` has to be disabled. It is not allowed to emulate a highlight function by a digital gamma table. The backend has to disable (or not define) this option when the scanner does not support an analog (hardware) highlight function.

This option is not mandatory, but if a backend does support it, it must implement it in a manner consistent with the above definition.

### 4.5.13 Turn lamp on and off

The option `lamp-on` is used to turn the lamp of the scanner on. The type of this option is `SANE_TYPE_BUTTON`. The unit is `SANE_UNIT_NONE`. When the option is set then the lamp of the scanner is turned on.

The option `lamp-off` is used to turn the lamp of the scanner off. The type of this option is `SANE_TYPE_BUTTON`. The unit is `SANE_UNIT_NONE`. When the option is set then the lamp of the scanner is turned off.

These options are not mandatory, but if a backend does support them, it must implement them in a manner consistent with the above definition.

### 4.5.14 Scanner buttons

Some scanners have buttons which state can be read by the scanner driver. It is necessary to implement a locking function for the buttons because it is possible that several frontends try to connect to the same backend/scanner at the same time. Imagine what could happen when no locking would be implemented: Five people have started a scanning application which is connected via network to the scanner you want to use. You start a frontend, put a paper to the scanner and press the scan-button on the scanner. The scanner does scan three times (because three frontends asked the button status when you pressed the button). For three people the image is saved to the harddisk, but it is not sure that your frontend did scan the image.

A backend that does make available the scanner-buttons has to implement the following options:
`scanner-buttons-lock` is of type `SANE_TYPE_BOOL`, default = `SANE_FALSE`
`scanner-buttons-status` is of type `SANE_TYPE_INT`, default = 0
`scanner-buttons-status-update` is of type `SANE_TYPE_BUTTON`
When setting these options the backend does not set `SANE_INFO_RELOAD_OPTIONS` or `SANE_INFO_RELOAD_PARAMS` if not explictly defined.

A frontend has to disable the usage of the scanner-buttons by default. This is important because other frontends will not be able to use the buttons when the button-functions are locked. Another important thing is that some scanners do not turn off their lamp when the driver does frequently talk to the scanner (what is done when reading the button status from the scanner).

- A frontend that wants to read the button status has to lock the button functions at first. For this it does set the option `scanner-buttons-lock` to `SANE_TRUE`. While setting the value of option `scanner-buttons-lock` to `SANE_TRUE` the backend does check if a lockfile (e.g. "backend"-buttons.lock) does exist. The lockfile has to be placed in a directory where every user has read and write access to.

  - If the lockfile does not exist then the backend creates the lockfile and writes the process ID (PID) of the backend to the file. Button access is allowed: the value of option `scanner-buttons-lock` is set to `SANE_TRUE`
  - If the file does exist and the backend PID is not the file PID then the backend has to check if the process with the PID stored in the lockfile still is running. If yes then the button access is not allowed: the value of option `scanner-buttons-lock` is set to `SANE_FALSE`. If not then the lockfile is recreated and the PID of the backend is stored in the lockfile, button access is allowed: the value of option `scanner-buttons-lock` is set to `SANE_TRUE`

- The frontend does read the value of option `scanner-buttons-lock`. If it is `SANE_TRUE` then the frontend has access to the scanner buttons. If it is `SANE_FALSE` then access has been denied.

- If the button access is allowed the frontend has to do the following about once per second (while not scanning):
  - The frontend does set option `scanner-buttons-status-update`. The backend checks if access to the buttons is allowed by comparing the backend PID with the lockfile PID. If access is allowed it does read the button status from the scanner and stores it in the option `scanner-buttons-status`, each bit represents a button, a value of 0 means the button is not pressed, a value of 1 means that the button is pressed. When the scanner is busy the backend must not wait, it has to return immedeatly and the button state keeps unchanged. The backend has to implement a timeout function. When no button has been pressed within a predefined time (e.g. 15 minutes) then the access permission is lost. In this case the backend does set option `scanner-buttons-lock` to `SANE_FALSE` and does set `SANE_INFO_RELOAD_OPTIONS` to inform the frontend that it has lost permission to access the scanner-button functions. If access is not allowed it does set the `scanner-buttons-status` to 0.

  - The frontend does read the value of option `scanner-buttons-status`

- When the frontend does exit or it does not want to use the buttons it does set option `scanner-buttons-lock` to `SANE_FALSE`. The backend does check if the backend PID and the lockfile PID are the same. If this is true then it removes the lockfile and sets the value of `scanner-buttons-lock` to `SANE_FALSE`.

  `sane_close()` should do the same as setting option `scanner-buttons-lock` to `SANE_FALSE`.