/*!
\page normalized_api Normalized C scan API (aka the solutions)


# Description

LibInsane has one C API. It is designed so it can wrap the Sane API, the WIA API,
or the TWAIN API without losing too many features.

This API is implemented by a variety of components:
- \ref sane.h "Wrapper for libsane API"
- \ref wia_ll.h "Wrapper for WIA2 low-level API"
- \ref twain.h "Wrapper for TWAIN API"
- \ref workarounds.h "Various wrappers that allow working transparently around bugs"
- \ref normalizers.h "Various wrappers that normalize the behaviors of scanners and drivers from an application standpoint"

The function \ref lis_safebet "lis_safebet()" stacks all the recommended implementations.
It is your recommended entry point to LibInsane.
Since all the components implement the same API, you can simply use the one provided by
\ref lis_safebet "lis_safebet()" without ever worrying about which components are actually used.


# Expected use of LibInsane

Expected order of calling when most of the normalizers are enabled:

- \ref lis_safebet "impl = lis_safebet()"
- \ref lis_api.list_devices "impl->list_devices()"
- \ref lis_item "dev" = \ref lis_api.get_device "impl->get_device()"
  - \ref lis_item "sources" = \ref lis_item.get_children "dev->get_children()"
    - \ref lis_option_descriptor "options" = \ref lis_item.get_options "sources[a]->get_options()"
      - \ref lis_option_descriptor.get_value "options[x]->fn.get_value()".
      - \ref lis_option_descriptor.set_value "options[x]->fn.set_value()".<br>
        Option that should always be set by the application:
        - \ref lis_api_normalizer_resolution "scan resolution (option \"resolution\")"
      - \ref lis_option_descriptor.get_value "options[y]->fn.get_value()".
      - \ref lis_option_descriptor.set_value "options[y]->fn.set_value()".
      - \ref lis_option_descriptor.get_value "options[z]->fn.get_value()".
      - \ref lis_option_descriptor.set_value "options[z]->fn.set_value()".
    - \ref lis_scan_session "scan_session" = \ref lis_item.scan_start "sources[a]->scan_start()"<br>
      From this point and until \ref lis_scan_session.end_of_feed return true,
      \ref lis_scan_session.cancel "scan_session->cancel()"
      can be called at any moment.
    - \ref lis_scan_session.get_scan_parameters "scan_session->get_scan_parameters()"
    - while not \ref lis_scan_session.end_of_feed "scan_session->end_of_feed()":
      - while not \ref lis_scan_session.end_of_page "scan_session->end_of_page()":
        - \ref lis_scan_session.scan_read "scan_session->scan_read()".
  - \ref lis_item.close "dev->close()"
- \ref lis_api.cleanup "cleanup()"

See \ref capi.h.

# Usage examples

## Scanning

See \ref quickstart.


## Stacking API implementations

If you don't want to use \ref lis_safebet, you can stack the API implementations
yourself.

Please note that you should use \ref lis_safebet in most applications. There shouldn't
be any reason not to use it. Don't hesitate to report a bug if \ref lis_safebet
doesn't work for you.

Once you have wrapped an implementation with another, you don't have to worry about the
first implementation. The wrapping one will take care of the wrapped one.

Quick and lazy example:

```
#include <libinsane/capi.h>
#include <libinsane/error.h>
#include <libinsane/normalizers.h>
#include <libinsane/sane.h>
#include <libinsane/workarounds.h>

struct lis_api *lets_stack(void)
{
    struct lis_api *impl;
    enum lis_error err;

    CHECK_ERR(lis_api_sane(&impl));
    CHECK_ERR(lis_api_workaround_opt_scan_resolution(impl, &impl));
    CHECK_ERR(lis_api_workaround_opt_names(impl, &impl));
    CHECK_ERR(lis_api_workaround_opt_values(impl, &impl));
    CHECK_ERR(lis_api_normalizer_source_nodes(impl, &impl));
    CHECK_ERR(lis_api_normalizer_min_one_source(impl, &impl));
    CHECK_ERR(lis_api_normalizer_all_opts_on_all_sources(impl, &impl));

    // impl is ready to roll
    return impl;
}
```

*/
