🐞Die SANE-API im Debugger

Ein kompletter Scan ist eine feste Folge von C-Aufrufen. Stelle Modus, Auflösung und Bereich ein, wähle ein Szenario – und gehe den Ablauf Aufruf für Aufruf durch. Rechts baut sich das Bild so auf, wie die Bytes aus sane_read() kommen.

🧪
Simulation im Browser. Diese Seite steuert keinen echten Scanner an – der Server hat keinen, und ein öffentlich erreichbarer Scanner wäre ein Sicherheitsrisiko. Der simulierte Scanner bildet das Verhalten der SANE-API nach (Vorbild: das SANE-Test-Backend test), alle Zahlen werden mit den echten Formeln berechnet.
Schritt 1 / 27 · Tasten ← →
init

sane_init()

SANE_STATUS_GOOD
SANE_Int version_code;
status = sane_init(&version_code, auth_callback);
Ergebnis
version_code = 0x0100001C = SANE_VERSION_CODE(1, 0, 28)
→ Major 1: Frontend und Backend sind kompatibel

Erster Aufruf überhaupt. Das Backend initialisiert sich und liefert seinen Versionscode. Nur die Major-Version entscheidet über Kompatibilität. Der optionale auth_callback wird aufgerufen, wenn ein Gerät Benutzer/Passwort verlangt (z. B. saned mit saned.users). Build 28 ist der Wert des echten test-Backends.

sane_init
Geräteliste
kein Handle
Leerlauf

🗺️Code-Flow laut Standard

sane_init()
 │
 ├─ sane_get_devices()          (jederzeit, kann langsam sein)
 │
 ├─ sane_open("backend:gerät")
 │   │
 │   ├─ sane_get_option_descriptor() ┐  beliebig gemischt,
 │   ├─ sane_control_option()         ├ nach RELOAD_OPTIONS
 │   ├─ sane_get_parameters()  (Schätzung) ┘ neu einlesen
 │   │
 │   ├─ sane_start() ◄──────────────┐  nächster Rahmen
 │   │   ├─ sane_get_parameters()   │  bzw. nächste Seite
 │   │   └─ sane_read() … EOF ──────┘
 │   │
 │   ├─ sane_cancel()           (immer, auch nach EOF)
 │   └─ sane_close()
 │
sane_exit()
FunktionZweck
sane_init(&version, auth)Backend initialisieren, Versionscode zurück
sane_exit()alles freigeben – immer als Letztes
sane_get_devices(&list, local_only)Liste der Geräte (NULL-terminiert)
sane_open(name, &h) / sane_close(h)Gerät öffnen/schließen
sane_get_option_descriptor(h, n)Beschreibung von Option n
sane_control_option(h, n, action, &v, &info)Option lesen / setzen / automatisch
sane_get_parameters(h, &p)Format, Pixel/Zeile, Bytes/Zeile, Zeilen, Tiefe
sane_start(h)Aufnahme eines Rahmens starten
sane_read(h, buf, maxlen, &len)nächsten Datenblock lesen
sane_cancel(h)Vorgang beenden – auch nach EOF Pflicht
sane_set_io_mode(h, non_blocking)blockierend (Standard) oder nicht blockierend
sane_get_select_fd(h, &fd)Dateideskriptor für select()/poll()
sane_strstatus(status)Statuscode als Text

🚦Status-Codes (SANE_Status)

CodeNamesane_strstatus()Bedeutung
0SANE_STATUS_GOOD"Success"Aufruf erfolgreich.
1SANE_STATUS_UNSUPPORTED"Operation not supported"Das Backend unterstützt die Operation nicht (z. B. nicht blockierendes Lesen).
2SANE_STATUS_CANCELLED"Operation was cancelled"Vorgang wurde mit sane_cancel() abgebrochen.
3SANE_STATUS_DEVICE_BUSY"Device busy"Gerät ist belegt (z. B. von einem anderen Programm geöffnet) – später erneut versuchen.
4SANE_STATUS_INVAL"Invalid argument"Ungültiges Argument – z. B. unbekannter Gerätename bei sane_open() oder unzulässiger Optionswert.
5SANE_STATUS_EOF"End of file reached"Kein Fehler: das Ende des aktuellen Rahmens ist erreicht.
6SANE_STATUS_JAMMED"Document feeder jammed"Papierstau im automatischen Einzug (ADF).
7SANE_STATUS_NO_DOCS"Document feeder out of documents"Der Einzug ist leer – bei --batch das normale Ende.
8SANE_STATUS_COVER_OPEN"Scanner cover is open"Deckel bzw. Klappe des Scanners ist offen.
9SANE_STATUS_IO_ERROR"Error during device I/O"Fehler bei der Kommunikation (USB, Netzwerk, SCSI).
10SANE_STATUS_NO_MEM"Out of memory"Speicher reicht nicht.
11SANE_STATUS_ACCESS_DENIED"Access to resource has been denied"Zugriff verweigert – z. B. saned-Benutzer/Passwort falsch.
12SANE_STATUS_WARMING_UP"Lamp not ready, please retry"Lampe wärmt noch auf (Erweiterung, nicht im Standard 1.06).
13SANE_STATUS_HW_LOCKED"Scanner mechanism locked for transport"Transportsicherung ist noch verriegelt (Erweiterung, nicht im Standard 1.06).

🧑‍💻Minimales Frontend in C

So wenig braucht ein eigenes Scanprogramm – Fehlerbehandlung gekürzt. Übersetzen mit: cc scan.c -o scan $(pkg-config --cflags --libs sane-backends)
#include <sane/sane.h>
#include <stdio.h>

int main(void) {
    SANE_Int version;
    SANE_Handle h;
    SANE_Parameters p;
    SANE_Byte buf[32768];
    SANE_Int len;
    SANE_Status st;

    sane_init(&version, NULL);
    if (sane_open("test:0", &h) != SANE_STATUS_GOOD) { sane_exit(); return 1; }

    sane_start(h);
    sane_get_parameters(h, &p);
    printf("%d x %d Pixel, %d Bytes/Zeile\n", p.pixels_per_line, p.lines, p.bytes_per_line);

    FILE *out = fopen("scan.raw", "wb");
    while ((st = sane_read(h, buf, sizeof buf, &len)) == SANE_STATUS_GOOD)
        fwrite(buf, 1, len, out);
    fclose(out);
    if (st != SANE_STATUS_EOF) fprintf(stderr, "Fehler: %s\n", sane_strstatus(st));

    sane_cancel(h);
    sane_close(h);
    sane_exit();
    return 0;
}