Jump to content

Print and Scan

From MukeWiki

AirPrint and AirScan

AirPrint, resp. Apple driverless printing, resp. tlacenie bez nutnosti instalacie drivers pre kazdy konkretny model tlaciarne. Analogicky AirScan pre skenovanie bez instalacie drivers. Zariadenie (tlaciaren, skener, multifunkcne all-in-one a pod.) je vacsinou pripojene cez lokalnu siet. Takze napr. s jednym notebookom mozeme tlacit/skenovat v roznych sietach (doma, firemna siet A, firemna siet B, na navsteve u znamych, resp. vsade, kde je zariadenie s AirPrint/AirScan technologiou) bez toho, aby sme instalovali drivers pre kazdy jeden konkretny model zariadenia. Je to pohodlne a funkcne riesenie.

AirPrint ponuka zatial skor moznosti zakladneho tlacenia, nie je to plnohodnotna nahrada ako v pripade nainstalovania vendor drivers. Ak potrebujeme vytlacit zakladny dokument (pdf, obrazok) plne si vystacime s AirPrint driverless printing. Ale ak potrebujeme vytlacit napr. fotografiu v max. kvalite a specifikovat konkretny papier, ktory je umiestneny v konkretnom zasobniku tlaciarne, vacsinou uz sme nuteni instalovat vendor drivers. Treba si uvedomit, ze pri pouzivani AirPrint nemusime absolutne nic instalovat, a teda, vyrobcovia takto prichadzaju o moznost "ponukat prave ich super spravne vyrobky, doplnky". V pripade AirScan su obmedzenia mensie a az na specificke pripady dnes plne supluje moznosti konfiguracie vendor drivers.

Dnes uz takmer vsetky novsie zariadenia podporuju driverless printing technologiu a je malo pravdepodobne vypustit novy model bez jej podpory. Kvoli licencnym politikam existuju 4 standardy pre driverless IPP printing, resp. 4 Page Description Languages (PDLs), ktore komunikuju s klientom cez Internet Printing Protocol (IPP). Rozdiel je v podstate len v podpore, vybere PDLs.

Driverless Printing Standards
Standard PDLs Note
AirPrint Apple Raster/URF, JPEG and PDF Apple's standard and is the most common and oldest driverless printing standard.
IPP Everywhere PWG Raster, JPEG and PDF Developed by the Printer Working Group (PWG) and is a completely open standard.
Mopria PCLm, PWG Raster and PDF Proprietary profile of IPP used for printing from Android and Microsoft Windows.
Wi-Fi Direct PCLm, PWG Raster and PDF Printers work as a Wi-Fi access point so that mobile devices can print direct.
List of driverless printers: https://openprinting.github.io/printers/.

SANE

SANE sa na rozdiel od TWAIN snazi dosledne oddelit ovladace konkretnych skenerov (backends, resp. scanner drivers) od grafickeho uzivatelskeho rozhrania (frontends, resp. user programs).

Fedora packages potrebne pre skenovanie:

  • sane-backendsrpm: sane-backends a sane-backends-libs (packages sane-backends-drivers-cameras and sane-backends-drivers-scanners len v pripade ak su potrebne vendor drivers)
  • sane-frontendsrpm: obsahuje specificke programy scanadf(1) a xcam(1) a package nie je potrebne instalovat
  • sane-airscanrpm: sane-airscan a libsane-airscan

$ dnf install sane-backends sane-backends-libs sane-airscan libsane-airscan

Za frontends programy mozno povazovat aj rozne graficke nadstavby nad SANE ako napr: simple-scan(1)rpm alebo jeden z prvych grafickych programov na skenovanie xsane(1)rpm. Dalej vsak budeme pouzivat len CLI scanimage(1)rpm.

NOTE prikaz sane-find-scanner(1)rpm vyhladava skenery pripojene cez USB controller (or SCSI adapter), ale nie cez sietove pripojenie.

SANE drivers baliky instaluju niekolko desiatok drivers (dir /usr/lib64/sane/) pre rozne modely od roznych vyrobcov. sane-dll(5) umoznuje ich dynamicke nacitavanie a konfiguruje sa cez subor /etc/sane.d/dll.conf. Druha moznost konfiguracie (s vyssou prioritou) je pridanie suboru, ktory obsahuje backend name (driver), do directory /etc/sane.d/dll.d/. Dnes je vsak pre sietove zariadenia tendencia preferovat (a presadzovat) pouzivanie driverless scanning protocol eSCL (AirScan), pripadne WSD.

$ sudo cp -p /etc/sane.d/dll.conf /etc/sane.d/dll.conf.orig
$ sudo sed -i '/^v4l/s/^/#/' /etc/sane.d/dll.conf   # disable 'v4l' devices at all (device v4l:/dev/video0)

NOTE Ak pouzivame vylucne len AirScan sietove skenery, tak v principe je mozne zmazat cely subor /etc/sane.d/dll.conf, co ale neprinesie ziadne vyhody, skor naopak. Clovek po case zabuda a po zapnuti nejakeho noveho USB skenera nebude mat jeho podporu, kedze si ju sam zrusil. Podpora pre AirScan v SANE je zabezpecene cez /etc/sane.d/dll.d/airscan file.

AirScan

SANE backend for AirScan (eSCL) and WSD document scanners. Similar to how most modern network printers support "driverless" printing, using the universal vendor-neutral printing protocol, many modern network scanners and MFPs support "driverless" scanning. sane-airscan(5) currently supports two protocols:

  • eSCL also known as Apple AirScan or AirPrint scanning (Scanner Control Language), preferred
  • WSD also known as Microsoft WSD (Web Services for Devices) or WS-Scan (proprietary protocol)

Most modern scanners can be accessed using eSCL or WSD protocols, with no additional configuration, and in most cases, the scanner will work out of the box. Na vyhladavanie sietoveho skenera pouzijeme prikaz airscan-discover(1)rpm.

Subor /etc/sane.d/dll.d/airscan zapina v SANE podporu pre AirScan a subor /etc/sane.d/airscan.conf jeho samotnu konfiguraciu. Section [devices] (konfiguracny subor /etc/sane.d/airscan.conf) nam umoznuje manualne pridat model pre konkretny skener (e.g. for non-discovery device). In section [options] option discovery enable/disable automatic device discovery. Vseobecne plati, cim konkretnejsie specifikujem, kde sa zariadenie (skener) nachadza, tym rychlejsie mam k nemu pristup. Obzvlast option discovery = disable (subor /etc/sane.d/airscan.conf) moze urychlit pristup ku skeneru o 20 – 30% (nie samotny proces skenovania).

NOTE Konfiguracny subor /etc/sane.d/airscan.conf konfiguruje SANE kniznicu airscan, a teda konfiguruje aj program scanimage(1), ale nie airscan-discover(1).

# See also How to Debug Scanning Issues.
$ SANE_DEBUG_DLL=255 SANE_DEBUG_SANEI_TCP=255 SANE_DEBUG_AIRSCAN=255 scanimage -L &> sane.discovery.out
$ SANE_DEBUG_AIRSCAN=255 scanimage -L
/etc/sane.d/airscan.conf
# $ airscan-discover   # Wi-Fi 'SAV Internet'
# [devices]
#   Brother MFC-T910DW = http://172.30.0.55:80/eSCL/, eSCL
#   Brother MFC-T910DW = http://172.30.0.55:80/WebServices/ScannerService, WSD
# $ avahi-resolve --address 172.30.0.55
# 172.30.0.55    BRW90324B17AD6E.local
#
# Brother MFC-T910DW = http://172.30.0.55:80/eSCL/, eSCL           ; direct IP
# Brother MFC-T910DW = http://BRW90324B17AD6E.local:80/eSCL/, eSCL ; mDNS hostname

[devices]
brother322 = http://BRW90324B17AD6E.local:80/eSCL/, eSCL ; Brother MFC-T910DW in room 322

[options]
# discovery = disable ; decreases access time to device, but hide all other devices

[blacklist]
# name = "*M234dw*"   ; HP LaserJet MFP M234dw
# name = "*3025*"     ; Xerox WorkCentre 3025
$ time scanimage > test.speed                                    # => 16.0 sec.
$ # export SANE_DEFAULT_DEVICE='airscan:e0:brother322'   # scanimage ENVIRONMENT
$ time scanimage --device 'airscan:e0:brother322' > test.speed   # => 14.3 sec.
SANE_AIRSCAN_DEVICE is sane-airscan ENVIRONMENT. This variable, if set, overrides all devices, manually configured in the configuration files and disables auto discovery. Create new [devices] section on the fly (and discovery = disable).
$ export SANE_AIRSCAN_DEVICE='escl:brother322:http://BRW90324B17AD6E.local:80/eSCL/'
$ time scanimage > test.speed                                    # => 13.5 sec. (discovery disabled)

NOTE Avahi, resp. multicast DNS (mDNS) vo Windows Subsystem for Linux (WSL) (by default) nefunguje. Prikazy ako airscan-discover alebo avahi-browse --all nam nenajdu ziadne zariadenia (non-discovery device). V tomto pripade je manualna konfiguracia nevyhnutna. Pre kazde zariadenie sa zada jeho IP adresa (hostname v lokalnej sieti generovany z MAC adresy pouziva mDNS mechanizmus, a teda nebude fungovat), see resolve .local names in WSL.

/etc/sane.d/airscan.conf (WSL BJ K30)
[devices]
Brother MFC-T910DW = http://192.168.0.175:80/eSCL/, eSCL
EPSON L6570 Series = http://192.168.0.123:443/eSCL/, eSCL

[options]
discovery = disable
Brother DCP-7070DW

Starsia sietova tlaciaren so skenerom Brother DCP-7070DW na domacej sieti spolu s pocitacom (otvorene porty 1025-65535) bez nejakych doplnkovych nastaveni a bez nainstalovaneho proprietarneho balika brscan4 od spolocnosti Brother.

$ airscan-discover
[devices]
  Brother DCP-7070DW = http://192.168.1.149:80/WebServices/ScannerService, WSD

$ scanimage --list-devices
device `airscan:w0:Brother DCP-7070DW' is a WSD Brother DCP-7070DW ip=192.168.1.149

$ scanimage --formatted-device-list "device name: '%d', vendor name: '%v', model name: '%m',%n\
scanner type: '%t' and index number: '%i'%n"
device name: 'airscan:w0:Brother DCP-7070DW', vendor name: 'WSD', model name: 'Brother DCP-7070DW',
scanner type: 'ip=192.168.1.149' and index number: '0'

$ scanimage --all-options --device-name 'airscan:w0:Brother DCP-7070DW'
Brother MFC-T910DW

Sietova tlaciaren so skenerom Brother MFC-T910DW na spolocnej pracovnej sieti s pocitacom (blokovane porty 1025-65535) bez nejakych doplnkovych nastaveni a bez proprietarneho balika brscan4 od spolocnosti Brother. Tlaciaren sa nachadza na zozname AirPrint devices (protokol eSCL).

$ airscan-discover     # temporary disable firewalld service
[devices]
  Brother MFC-T910DW = http://172.30.0.55:80/eSCL/, eSCL
  Brother MFC-T910DW = http://172.30.0.55:80/WebServices/ScannerService, WSD
  and other scanners

$ scanimage --list-devices   # protocol eSCL is preferred before WSD
device `airscan:e4:Brother MFC-T910DW' is a eSCL Brother MFC-T910DW ip=172.30.0.55

$ scanimage --formatted-device-list "device name: '%d', vendor name: '%v', model name: '%m',%n\
scanner type: '%t' and index number: '%i'%n"
device name: 'airscan:e4:Brother MFC-T910DW', vendor name: 'eSCL', model name: 'Brother MFC-T910DW',
scanner type: 'ip=172.30.0.55' and index number: '2'

Ta ista sietova tlaciaren so skenerom, ale s pouzitym driver z proprietarneho balika brscan4 od spolocnosti Brother.

$ scanimage --list-devices   # without airscan
device `brother4:net1;dev0' is a Brother Brother_MFC-T910DW MFC-T910DW

$ scanimage --formatted-device-list "device name: '%d', vendor name: '%v', model name: '%m',%n\
scanner type: '%t' and index number: '%i'%n"
device name: 'brother4:net1;dev0', vendor name: 'Brother', model name: 'Brother_MFC-T910DW',
scanner type: 'MFC-T910DW' and index number: '0'

airscan ponuka takmer vsetky moznosti konfiguracie pre skenovanie v porovnani s proprietarnym vendor driver brscan4 a rozdiely su vacsinou nepodstatne. Napr. pre tento konkretny model skenera, ak by som bol nuteny pouzit napr. rozlisenie 1200dpi (v praxi asi malo pravdepodobne), tak jedine s pouzitim brscan4 drivers. Vacsie moznosti vyberu roznych rezimov skenovanie (Color, Gray, Black & White a pod.) plne suplujem pomocou magick(1)rpm programu (post processing). Dnes na bezne skenovanie plne postacuje airscan (pre mnozstvo modelov) bez nutnosti instalacia vendor proprietarnych drivers (pre kazdy konkretny model).

$ scanimage --all-options --device-name 'airscan:e0:Brother MFC-T910DW'   # eSCL protocol (default and preferred)
   --resolution 100|200|300|600dpi [300]
   --mode       Color|Gray [Color]
   --source     Flatbed|ADF [Flatbed]
$ scanimage --all-options --device-name 'airscan:w0:Brother MFC-T910DW'   # WSD protocol
   --resolution 100|200|300dpi [300]
   --mode       Color|Gray [Color]
   --source     Flatbed|ADF [Flatbed]
$ scanimage --all-options --device-name 'brother4:net1;dev0'              # brscan4
   --resolution 100|150|200|300|400|600|1200|2400|4800|9600dpi [200]
   --mode       Black & White|Gray[Error Diffusion]|True Gray|24bit Color[Fast] [24bit Color[Fast]]
   --source     FlatBed|ADF(left aligned)|ADF(centrally aligned) [ADF(left aligned)]

scanimage

Na samotne skenovanie budeme dalej pouzivat CLI scanimage(1)rpm a dalsie upravy (post processing) pomocou CLI magick(1)rpm programu, resp. CLI tiffcp(1)rpm pre "archivacny" TIFF format. scanimage supported formats (sane-backends-1.4.0, released 2025-05): PNM (PBM for black-and-white, PGM for grayscale and PPM for color images) by default, TIFF (black-and-white, grayscale or color and as uncompressed lossless), PNG, JPEG (compression level 75 only) and PDF (pdf over 75% jpeg).

$ scanimage --list-devices
device `airscan:e0:Brother MFC-T910DW' is a eSCL Brother MFC-T910DW ip=172.30.0.55
$ scanimage --help --device-name 'airscan:e0:Brother MFC-T910DW'

$ scanimage --device-name 'airscan:e0:Brother MFC-T910DW' --format png > scan.image.png
$ scanimage --device-name 'airscan:e0:Brother MFC-T910DW' --output-file scan.image.tiff
# don't convert from scanimage --format jpeg (JPEG compression level 75 only, no option to change jpeg quality)
$ scanimage --resolution 600 --mode Color | convert - -quality 90 scan.photo.q90.jpeg
$ scanimage --format png --resolution 300 | convert - -monochrome scan.mono.document.png
NOTE jpeg: convert ppm → jpeg is identical as convert ppm → png → jpeg

# use --batch with document feeders (ADF)
$ scanimage --source ADF --format png --batch=scan.$(date +%Y%m%d.%H%M%S).p%03d.png

CUPS

Niekedy v 2020 – 2021 Apple prestal aktivne vyvijat CUPS (Common UNIX Printing System), co bolo sposobene odchodom hlavneho vyvojara (Michael Sweet) zo spolocnosti Apple. OpenPrinting organizacia (patriaca do rodiny Linux Foundation) prebera dalsi vyvoj CUPS spolu s jeho povodnym hlavnym vyvojarom. Dnes uz CUPS znamena OpenPrinting CUPS.

CUPS supports printing to AirPrint and IPP Everywhere printers. Network and local (USB) printers with (legacy) PPD-based printer drivers will be removed in OpenPrinting CUPS v3.
NOTE Models other than everywhere are deprecated and will not be supported in a future version of CUPS. The everywhere driver is used for nearly all modern networks printers sold since about 2009.

Fedora CUPS packages: cupsrpm, cups-browsedrpm, cups-filtersrpm and libcupsfiltersrpm.

$ dnf install cups cups-client cups-filesystem cups-filters cups-libs
$ dnf install cups-browsed cups-filters-driverless cups-ipptool

Dir /etc/cups/ obsahuje rozne konfiguracne subory: cupsd.conf(5), cups-files.conf(5), printers.conf(5), cups-browsed.conf(5) a podobne.

OpenPrinting CUPS main documentation: Printer Administration, Using Network Printers or Firewalls and man pages lpadmin(8) and lpinfo(8).

Connection (see also Avahi section):

  • dnssd:// pouziva DNS-SD (DNS Service Discovery) over mDNS (multicast DNS) na automaticke objavovanie zriadeni v lokalnej sieti (v Linux svete vacsinou cez avahi-daemon.service). Zariadenie samo inzeruje (ponuka) najvhodnejsi protokol pripojenia (cim nizsia hodnota priority tym vacsia priorita). CUPS takto objavuje zariadenia a podla dostupnych informacii moze vybrat alebo ponuknut vhodne pripojenie. Napr.
uri = dnssd://<printer_model>._ipp._tcp.local/?uuid=<uuid> IPP printing service (recommended)
uri = dnssd://<printer_model>._pdl-datastream._tcp.local/ RAW/JetDirect/AppSocket printing service
uri = dnssd://<printer_model>._printer._tcp.local/ LPD/LPR printing service
  • ipp:// moderny, standardny protokol na tlac v sieti. Komunikaciu priamo so zariadenim. Napr.
uri = ipp://<printer_address>:631/ipp/print
  • socket:// priama a rychla tlac dat (RAW or JetDirect or AppSocket). Napr.
uri = socket://<printer_address>:9100
  • lpd:// starsi zakladny UNIX styl tlace (LPD or LPR). Napr.
uri = lpd://<printer_address>:515/LPDQUEUE

Preferovat ipp:// connection (only protocol that CUPS supports natively). V pripade modelov starsich tlaciarni, ktore este nepodporuje IPP, tak skor uprednostnovat rychly a jednoduchy socket:// pred starsim lpd:// sietovym protokolom.

Network printing protocols supported by CUPS
CUPS URI DNS-SD service Protocol Port Note
ipp:// _ipp._tcp IPP 631 moderny plnohodnotny printing protocol
socket:// _pdl-datastream._tcp RAW/JetDirect/AppSocket 9100 priamy prenos print dat cez TCP
lpd:// _printer._tcp LPD/LPR 515 starsi Unix printing protocol
dnssd:// DNS-SD service discovery — CUPS discovery backend/URI objavenie tlacovej sluzby cez DNS-SD

Choosing CUPS Network Protocol
# Brother DCP-7070DW

### Internet Printing Protocol (IPP)
$ lpadmin -p test01 -E -v 'ipp://BRN001BA9EBD873.local:631/duerqxesz5090' -m everywhere
lpadmin: Unable to create PPD: No IPP attributes.
$ lpadmin -p test02 -E -v 'ipp://BRN001BA9EBD873.local:631/duerqxesz5090' -m drv:///brlaser.drv/br7070d.ppd
PRINTING: Error, "The printer configuration is incorrect or the printer no longer exists."
NOTE: Brother DCP-7070DW has a fake IPP protocol (not working)

### AppSocket Protocol (aka JetDirect)
$ lpadmin -p test03 -E -v 'socket://BRN001BA9EBD873.local:9100' -m drv:///brlaser.drv/br7070d.ppd
$ lpadmin -p test03 -E -v 'socket://BRN001BA9EBD873.local'      -m drv:///brlaser.drv/br7070d.ppd
$ lpadmin -p test03 -E -v 'socket://BRN001BA9EBD873'            -m drv:///brlaser.drv/br7070d.ppd
PRINTING: OK
URI NOTE: BRN001BA9EBD873.local:9100 = BRN001BA9EBD873.local = BRN001BA9EBD873

### Line Printer Daemon (LPD) Protocol
$ lpadmin -p test04 -E -v 'lpd://BRN001BA9EBD873.local:515/duerqxesz5090' -m drv:///brlaser.drv/br7070d.ppd
PRINTING: OK
$ lpadmin -p test05 -E -v 'lpd://BRN001BA9EBD873/BINARY_P1'               -m drv:///brlaser.drv/br7070d.ppd
PRINTING: OK
URI NOTE: BRN001BA9EBD873.local:515  = BRN001BA9EBD873.local = BRN001BA9EBD873
          differnet only LPD queue: 'duerqxesz5090' vs 'BINARY_P1'

Driver:

  • Pre ipp:// protokol preferovat driver everywhere. Novsie zariadenia by mali fungovat bez problemov.
  • Pre ostatne protokoly su potrebne (legacy) PPD-based printer drivers, t.j. rozne "generic" drivers, resp. proprietarne vendor drivers od vyrobcov zariadeni. OpenPrinting listing printer drivers and printers with recommendations on which driver(s) to use for which printer. Ako uz bolo spomenute, v buducnosti bude podpora PPD-based printer drivers v CUPS odstranena.

Preferovat pouzivanie ipp:// connection, resp. ipp:// cez "sprostredkujuci" dnssd:// protocol spolu s everywhere driver.

# main tools: ippfind(1)rpm, ipptool(1)rpm, lpinfo(8)rpm and lpadmin(8)rpm

# temporary disable firewalld service
# or open 5353 port (firewalld <service name="mdns"/>) + specific printer protocol connection port

NOTE ippfind(1) find internet printing protocol printers (not only IPP services) via DNS-SD. Primary finds '_ipp._tcp' (IPP), but also supports '_printer._tcp' (LPD).

$ ippfind
ipp://BRW90324B17AD6E.local:631/ipp/print   # Brother MFC-T910DW
$ ipptool -tv ipp://BRW90324B17AD6E.local:631/ipp/print get-printer-attributes.test
# more test in dir /usr/share/cups/ipptool/

$ lpinfo -v   # lpinfo -l -v
network dnssd://Brother%20MFC-T910DW._ipp._tcp.local/?uuid=e3248000-80ce-11db-8000-3c2af47070ba
network ipp://Brother%20MFC-T910DW._ipp._tcp.local/

$ lpadmin -p Brother_MFC-T910DW -E -v "ipp://172.30.0.55:631/ipp/print" -m everywhere
$ lpadmin -p Brother_MFC-T910DW -E -v "ipp://BRW90324B17AD6E.local:631/ipp/print" -m everywhere
$ avahi-resolve --address 172.30.0.55
172.30.0.55	BRW90324B17AD6E.local
$ avahi-resolve --name BRW90324B17AD6E.local
BRW90324B17AD6E.local	172.30.0.55
$ lpadmin -p Brother_MFC-T910DW -E -v "ipp://Brother%20MFC-T910DW._ipp._tcp.local/" -m everywhere
Brother MFC-T910DW

Multifunkcna atramentova tlaciaren s podporou IPP Everywhere, uvedena na trh asi v 2018. Tato tlaciaren plne demonstruje nevhodny pristup vyrobcov k ovladacom pre open source komunitu. Brother pre Linux poskytuje len proprietarne ovladace svojich zariadeni (pre konkretny model dokonca len pre i386 architekturu). The problem with Brother printers is that Brother has pulled the printing functionality out of hardware and put it in software, which is proprietary. The "driver" is a Linux binary wrapper. Without this wrapper, the printer is useless, unless you can somehow get Linux emulation to run the binary. Nastastie vsak podporuje IPP Everywhere.

# connection: ipp, driver: everywhere
$ lpadmin -p Brother-MFC-T910DW -E -v "ipp://BRW90324B17AD6E.local:631/ipp/print" -m everywhere
HP LaserJet 600 M603 and HP LaserJet M611

Laserove tlaciarne s podporou IPP Everywhere. Open source ovladace su k dispozicii prostrednictvom hpliprpm (HP's Linux Imaging and Printing software) $ dnf install hplip hplip-common hplip-libs

NOTE HP LaserJet 600 M603 tlaciaren (model z roku 2011) pri pouziti everywhere driver vznika specificky problem pri tlaci. Niektore pismena s diakritikou (ž alebo š) v niektorych PDF dokumentoch (VEGA posudok) sa vytlacia nekorektne. Je potrebne pouzit iny driver (hplip pripadne generic). HP LaserJet M611 tlaciaren (model z roku 2019) tlaci s everywhere driver vsetko bez problemov.

# connection: ipp, driver: everywhere   # preferred
$ lpadmin -p HP-LaserJet-M603 -L caffe327 -E -v "ipp://10.0.0.26:631/ipp/print" -m everywhere
$ lpadmin -p HP-LaserJet-M611 -L caffe327 -E -v "ipp://10.0.0.23:631/ipp/print" -m everywhere

# connection: ipp, driver: hplip        # obsolete, more printing options than everywhere, identical print quality
$ lpadmin -p HP-LaserJet-M603_hplip -L caffe327 -E -v "ipp://10.0.0.26:631/ipp/print" \
          -m lsb/usr/HP/hp-laserjet_600_m601_m602_m603-ps.ppd.gz
$ lpadmin -p HP-LaserJet-M611_hplip -L caffe327 -E -v "ipp://10.0.0.23:631/ipp/print" \
          -m lsb/usr/HP/hp-laserJet_m610_m611_m612-ps.ppd.gz
# connection: ipp, driver: generic      # obsolete, less printing options, identical print quality
$ lpadmin -p HP-generic -E -v "ipp://<ip-address>:631/ipp/print" -m drv:///sample.drv/laserjet.ppd

$ lpinfo -m | grep -i laserjet.ppd   # lpinfo with option '-m' is deprecated (printer drivers are deprecated)
# option Duplexer (by default) 'Not Installed', change to 'Installed'

Avahi

Service discovery is the process of automatically detecting devices and services on a computer network. It aims to reduce the manual configuration effort required from users and administrators. For example you can plug into a network and instantly find printers to print to, files to look at and people to talk to.

Fedora avahirpm subpackages:

$ dnf install avahi avahi-glib avahi-libs avahi-tools

Avahi implements free zeroconf (Zero-configuration networking) specification. Is a free (LGPL) implementation of DNS-SD (DNS Service Discovery) over mDNS (multicast DNS), compatible with Apple Bonjour. Avahi provides local hostname resolution using a hostname.local naming scheme (mDNS UDP port 5353).

Avahi uses service type database. See also which services are discovered in source files sane-airscan/airscan-mdns.c and cups/backend/dnssd.c or in man page ippfind(1)rpm.

AirPrint je zalozeny na mDNS (Bonjour) a IPP. mDNS protokol sa pouziva na vyhladanie (discovery) zariadenia a IPP na samotne tlacenie na tomto zariadeni. Windows zariadenia pouzivaju Web Services for Devices (WSD) na vyhladanie zariadenia a Line Printer Daemon protocol (LPD) or LPR or JetDirect (RAW) pre samotne tlacenie. Android zariadenia a Windows 10 podporuju Mopria Alliance print standard, co je to iste ako AirPrint v Apple svete. See also:

DNS-SD / mDNS service type protocol port notes
_printer._tcp lpd:// LPD (Line Printer Daemon) or LPR 515 starsi UNIX styl tlace (generic print)
_ipp._tcp ipp:// IPP (Internet Printing Protocol) 631 moderny, odporucany a bezpecny sposob tlace
_pdl-datastream._tcp socket:// RAW or JetDirect or AppSocket 9100 rychla, priama tlac dat (napr. PCL, PS), no security
DNS-SD / mDNS service type notes
_scanner._tcp generic scanner, ktory moze pouzivat rozne protokoly resp. sluzby (SANE)
_uscan._tcp eSCL AirPrint scanning or AirScan, moderny a odporucany sposob
not available WSD nepouziva mDNS protokol, ale Microsoft proprietarny protokol zalozeny na WS-Discovery
NOTE avahi-browse vyhladava "len" eSCL skenery, airscan-discover vyhladava eSCL aj WSD skenery.
# temporary disable firewalld or allow mDNS traffic on 5353 port (firewalld <service name="mdns"/>)

$ avahi-browse --all --terminate # --resolve

$ avahi-browse --resolve --terminate _uscan._tcp   # eSCL AirPrint scanning
# similar as airscan-discover -d
$ avahi-browse --resolve --terminate _ipp._tcp     # IPP (Internet Printing Protocol)
# similar as ippfind (supported services: '_ipp._tcp' and '_printer._tcp') or lpinfo -l -v

$ avahi-resolve --address 192.168.0.123
192.168.0.123   EPSON7B55E9.local
$ avahi-resolve --name EPSON7B55E9.local
EPSON7B55E9.local       192.168.0.123
Brother MFC-T910DW
# Brother MFC-T910DW
$ avahi-resolve --address 172.30.0.55   # WiFi 'SAV Internet' and temporary disable firewalld
172.30.0.55    BRW90324B17AD6E.local
$ avahi-resolve --name BRW90324B17AD6E.local
BRW90324B17AD6E.local    172.30.0.55

$ avahi-browse --all --terminate --resolve
+ wlp1s0f0u2 IPv4 Brother MFC-T910DW                            _http._tcp           local
+ wlp1s0f0u2 IPv4 Brother MFC-T910DW                            _uscan._tcp          local
+ wlp1s0f0u2 IPv4 Brother MFC-T910DW                            _printer._tcp        local
+ wlp1s0f0u2 IPv4 Brother MFC-T910DW                            _ipp._tcp            local
+ wlp1s0f0u2 IPv4 Brother MFC-T910DW                            _pdl-datastream._tcp local
+ wlp1s0f0u2 IPv4 Brother MFC-T910DW                            _scanner._tcp        local

= wlp1s0f0u2 IPv4 Brother MFC-T910DW                            _http._tcp           local
   hostname = [BRW90324B17AD6E.local]
   address = [172.30.0.55]
   port = [80]
   txt = []
= wlp1s0f0u2 IPv4 Brother MFC-T910DW                            _uscan._tcp          local
   hostname = [BRW90324B17AD6E.local]
   address = [172.30.0.55]
   port = [80]
   txt = ["duplex=F" "is=adf,platen" "cs=binary,grayscale,color" "UUID=e3248000-80ce-11db-8000-3c2af47070ba" "pdl=application/pdf,image/jpeg" "note=UEF SAV 322" "ty=Brother MFC-T910DW" "rs=eSCL" "representation=http://BRW90324B17AD6E.local./icons/device-icons-128.png" "adminurl=http://BRW90324B17AD6E.local./net/net/airprint.html" "vers=2.63" "txtvers=1"]
= wlp1s0f0u2 IPv4 Brother MFC-T910DW                            _printer._tcp        local
   hostname = [BRW90324B17AD6E.local]
   address = [172.30.0.55]
   port = [515]
   txt = ["UUID=e3248000-80ce-11db-8000-3c2af47070ba" "TBCP=F" "Transparent=T" "Binary=T" "PaperCustom=T" "Scan=T" "Fax=T" "Duplex=T" "Copies=F" "Color=T" "usb_CMD=HBP,PJL" "usb_MDL=MFC-T910DW" "usb_MFG=Brother" "priority=50" "adminurl=telnet://BRW90324B17AD6E.local./" "product=(Brother MFC-T910DW)" "ty=Brother MFC-T910DW" "note=UEF SAV 322" "rp=duerqxesz5090" "pdl=application/octet-stream,image/urf,image/jpeg,image/pwg-raster,application/vnd.brother-hbp" "qtotal=1" "txtvers=1"]
= wlp1s0f0u2 IPv4 Brother MFC-T910DW                            _ipp._tcp            local
   hostname = [BRW90324B17AD6E.local]
   address = [172.30.0.55]
   port = [631]
   txt = ["mopria-certified=1.3" "print_wfds=T" "UUID=e3248000-80ce-11db-8000-3c2af47070ba" "PaperMax=legal-A4" "kind=document,envelope,postcard,photo" "URF=SRGB24,W8,CP1,IS19-1,MT1-8-11,OB9,PQ4-5,RS200-300,OFU0,V1.4,DM3" "rfo=ipp/faxout" "TBCP=F" "Transparent=T" "Binary=T" "PaperCustom=T" "Scan=T" "Fax=T" "Duplex=T" "Copies=F" "Color=T" "usb_CMD=HBP,PJL" "usb_MDL=MFC-T910DW" "usb_MFG=Brother" "priority=25" "adminurl=http://BRW90324B17AD6E.local./net/net/airprint.html" "product=(Brother MFC-T910DW)" "ty=Brother MFC-T910DW" "note=UEF SAV 322" "rp=ipp/print" "pdl=application/octet-stream,image/urf,image/jpeg,image/pwg-raster,application/vnd.brother-hbp" "qtotal=1" "txtvers=1"]
= wlp1s0f0u2 IPv4 Brother MFC-T910DW                            _pdl-datastream._tcp local
   hostname = [BRW90324B17AD6E.local]
   address = [172.30.0.55]
   port = [9100]
   txt = ["UUID=e3248000-80ce-11db-8000-3c2af47070ba" "TBCP=T" "Transparent=F" "Binary=T" "PaperCustom=T" "Scan=T" "Fax=T" "Duplex=T" "Copies=F" "Color=T" "usb_CMD=HBP,PJL" "usb_MDL=MFC-T910DW" "usb_MFG=Brother" "priority=75" "adminurl=telnet://BRW90324B17AD6E.local./" "product=(Brother MFC-T910DW)" "ty=Brother MFC-T910DW" "note=UEF SAV 322" "pdl=application/octet-stream,image/urf,image/jpeg,image/pwg-raster,application/vnd.brother-hbp" "qtotal=1" "txtvers=1"]
= wlp1s0f0u2 IPv4 Brother MFC-T910DW                            _scanner._tcp        local
   hostname = [BRW90324B17AD6E.local]
   address = [172.30.0.55]
   port = [54921]
   txt = ["flatbed=T" "feeder=T" "button=T" "mdl=MFC-T910DW" "mfg=Brother" "ty=Brother MFC-T910DW" "adminurl=telnet://BRW90324B17AD6E.local./" "note=UEF SAV 322" "txtvers=1"]
$ airscan-discover
[devices]
  Brother MFC-T910DW = http://172.30.0.55:80/eSCL/, eSCL
  Brother MFC-T910DW = http://172.30.0.55:80/WebServices/ScannerService, WSD

$ ippfind   # _ipp._tcp by default
ipp://BRW90324B17AD6E.local:631/ipp/print
$ ippfind _printer._tcp
lpd://BRW90324B17AD6E.local:515/duerqxesz5090
$ ipptool -tv ipp://BRW90324B17AD6E.local:631/ipp/print get-printer-attributes.test | grep -iE "printer attributes|ipp-versions"
    Get printer attributes using get-printer-attributes                  [PASS]
        ipp-versions-supported (1setOf keyword) = 1.0,1.1,2.0

$ lpinfo -l -v
Device: uri = dnssd://Brother%20MFC-T910DW._ipp._tcp.local/?uuid=e3248000-80ce-11db-8000-3c2af47070ba
        class = network
        info = Brother MFC-T910DW
        make-and-model = Brother MFC-T910DW
        device-id = MFG:Brother;MDL:MFC-T910DW;CMD:HBP,PJL;
        location = 
        NOTE Driver: IPP Everywhere 
Device: uri = ipp://Brother%20MFC-T910DW._ipp._tcp.local/
        class = network
        info = Brother MFC-T910DW (driverless)
        make-and-model = Brother MFC-T910DW
        device-id = MFG:Brother;MDL:MFC-T910DW;CMD:PWGRaster,AppleRaster,URF,JPEG,PWG;
        location = 
        NOTE Driver: IPP Everywhere (to same as for dnssd connection)
Device: uri = lpd://BRW90324B17AD6E/BINARY_P1
        class = network
        info = Brother MFC-T910DW
        make-and-model = Brother MFC-T910DW
        device-id = MFG:Brother;CMD:HBP,PJL;MDL:MFC-T910DW;CLS:PRINTER;CID:Brother Generic Jpeg Type2;
        location = UEF SAV 322
        NOTE Driver: vendor proprietary or another suitable driver
Brother DCP-7070DW
# Brother DCP-7070DW
$ avahi-resolve --address 192.168.1.149   # KE TN2 LAN
192.168.1.149	BRN001BA9EBD873.local
$ avahi-resolve --name BRN001BA9EBD873.local
BRN001BA9EBD873.local	192.168.1.149

$ avahi-browse --all --terminate --resolve
+ enp7s0 IPv4 Brother DCP-7070DW                            _http._tcp           local
+ enp7s0 IPv4 Brother DCP-7070DW                            _ipp._tcp            local
+ enp7s0 IPv4 Brother DCP-7070DW                            _printer._tcp        local
+ enp7s0 IPv4 Brother DCP-7070DW                            _pdl-datastream._tcp local

= enp7s0 IPv4 Brother DCP-7070DW                            _http._tcp           local
   hostname = [BRN001BA9EBD873.local]
   address = [192.168.1.149]
   port = [80]
   txt = []
= enp7s0 IPv4 Brother DCP-7070DW                            _ipp._tcp            local
   hostname = [BRN001BA9EBD873.local]
   address = [192.168.1.149]
   port = [631]
   txt = ["TBCP=F" "Transparent=T" "Binary=T" "PaperCustom=T" "Duplex=F" "Copies=T" "Color=F" "usb_MDL=DCP-7070DW" "usb_MFG=Brother" "priority=50" "adminurl=http://BRN001BA9EBD873.local./" "product=(Brother DCP-7070DW)" "ty=Brother DCP-7070DW" "rp=duerqxesz5090" "pdl=application/vnd.hp-PCL" "qtotal=1" "txtvers=1"]
= enp7s0 IPv4 Brother DCP-7070DW                            _printer._tcp        local
   hostname = [BRN001BA9EBD873.local]
   address = [192.168.1.149]
   port = [515]
   txt = ["TBCP=F" "Transparent=T" "Binary=T" "PaperCustom=T" "Duplex=F" "Copies=T" "Color=F" "usb_MDL=DCP-7070DW" "usb_MFG=Brother" "priority=75" "adminurl=http://BRN001BA9EBD873.local./" "product=(Brother DCP-7070DW)" "ty=Brother DCP-7070DW" "rp=duerqxesz5090" "pdl=application/vnd.hp-PCL" "qtotal=1" "txtvers=1"]
= enp7s0 IPv4 Brother DCP-7070DW                            _pdl-datastream._tcp local
   hostname = [BRN001BA9EBD873.local]
   address = [192.168.1.149]
   port = [9100]
   txt = ["TBCP=T" "Transparent=F" "Binary=T" "PaperCustom=T" "Duplex=F" "Copies=T" "Color=F" "usb_MDL=DCP-7070DW" "usb_MFG=Brother" "priority=25" "adminurl=http://BRN001BA9EBD873.local./" "product=(Brother DCP-7070DW)" "ty=Brother DCP-7070DW" "pdl=application/vnd.hp-PCL" "qtotal=1" "txtvers=1"]
$ airscan-discover
[devices]
  Brother DCP-7070DW = http://192.168.1.149:80/WebServices/ScannerService, WSD

$ ippfind   # _ipp._tcp by default
ipp://BRN001BA9EBD873.local:631/duerqxesz5090
$ ippfind _printer._tcp
lpd://BRN001BA9EBD873.local:515/duerqxesz5090
$ ipptool -tv ipp://BRN001BA9EBD873.local:631/duerqxesz5090 get-printer-attributes.test | grep -i "printer attributes"
    Get printer attributes using get-printer-attributes                  [FAIL]
# NOTE Tato tlaciaren v skutocnosti nepodporuje IPP napriek tomu, ze sa tak tvari (phantom/fake IPP printer):
"rp=duerqxesz5090" (resource path in '_ipp._tcp')

$ lpinfo -l -v
Device: uri = dnssd://Brother%20DCP-7070DW._pdl-datastream._tcp.local/
        class = network
        info = Brother DCP-7070DW
        make-and-model = Brother DCP-7070DW
        device-id = MFG:Brother;MDL:DCP-7070DW;CMD:PCL;
        location = 
        NOTE Driver: ToDo
Device: uri = lpd://BRN001BA9EBD873/BINARY_P1
        class = network
        info = Brother DCP-7070DW
        make-and-model = Brother DCP-7070DW
        device-id = MFG:Brother;CMD:PJL,PCL,PCLXL;MDL:DCP-7070DW;CLS:PRINTER;CID:Brother Laser Type1;
        location = 
        NOTE Driver: vendor proprietary or another suitable driver
EPSON L6570 Series
# EPSON L6570 Series
$ avahi-browse --all --terminate --resolve
+ enp7s0 IPv4 EPSON L6570 Series                            _http._tcp           local
+ enp7s0 IPv4 EPSON L6570 Series                            _smb._tcp            local
+ enp7s0 IPv4 EPSON L6570 Series                            _printer._tcp        local
+ enp7s0 IPv4 EPSON L6570 Series                            _ipp._tcp            local     # _ipps._tcp
+ enp7s0 IPv4 EPSON L6570 Series                            _pdl-datastream._tcp local
+ enp7s0 IPv4 EPSON L6570 Series                            _uscan._tcp          local     # _uscans._tcp
+ enp7s0 IPv4 EPSON L6570 Series                            _scanner._tcp        local

= enp7s0 IPv4 EPSON L6570 Series                            _http._tcp           local
   hostname = [EPSON7B55E9.local]
   address = [192.168.0.123]
   port = [80]
   txt = []
= enp7s0 IPv4 EPSON L6570 Series                            _smb._tcp            local
   hostname = [EPSON7B55E9.local]
   address = [192.168.0.123]
   port = [445]
   txt = []
= enp7s0 IPv4 EPSON L6570 Series                            _printer._tcp        local
   hostname = [EPSON7B55E9.local]
   address = [192.168.0.123]
   port = [515]
   txt = ["note=" "adminurl=http://EPSON7B55E9.local.:80/PRESENTATION/BONJOUR" "qtotal=1" "rp=auto" "pdl=application/vnd.epson.escpr" "product=(EPSON L6570 Series)" "usb_MDL=L6570 Series" "usb_MFG=EPSON" "ty=EPSON L6570 Series" "priority=50" "txtvers=1"]
= enp7s0 IPv4 EPSON L6570 Series                            _ipp._tcp            local     # _ipps._tcp identical
   hostname = [EPSON7B55E9.local]
   address = [192.168.0.123]
   port = [631]
   txt = ["TLS=1.2" "UUID=cfe92100-67c4-11d4-a45f-dccd2f7b55e9" "note=" "adminurl=http://EPSON7B55E9.local.:80/PRESENTATION/BONJOUR" "priority=30" "mopria-certified=2.0" "URF=CP1,PQ4-5,OB9,OFU0,RS300-600,SRGB24,W8,DM3,IS1-2-18,V1.4,MT1-3-6-8-10-11-12" "PaperMax=legal-A4" "kind=document,envelope,photo" "rfo=ipp/faxout" "Fax=T" "Scan=T" "Duplex=T" "Color=T" "qtotal=1" "rp=ipp/print" "pdl=application/octet-stream,image/pwg-raster,image/urf,image/jpeg,application/vnd.epson.escpr" "product=(EPSON L6570 Series)" "usb_MDL=L6570 Series" "usb_MFG=EPSON" "ty=EPSON L6570 Series" "txtvers=1"]
= enp7s0 IPv4 EPSON L6570 Series                            _pdl-datastream._tcp local
   hostname = [EPSON7B55E9.local]
   address = [192.168.0.123]
   port = [9100]
   txt = ["note=" "adminurl=http://EPSON7B55E9.local.:80/PRESENTATION/BONJOUR" "qtotal=1" "pdl=application/vnd.epson.escpr" "product=(EPSON L6570 Series)" "usb_MDL=L6570 Series" "usb_MFG=EPSON" "ty=EPSON L6570 Series" "priority=40" "txtvers=1"]
= enp7s0 IPv4 EPSON L6570 Series                            _uscan._tcp          local     # _uscans._tcp identical
   hostname = [EPSON7B55E9.local]
   address = [192.168.0.123]
   port = [443]
   txt = ["representation=https://EPSON7B55E9.local.:443/PRESENTATION/AIRPRINT/PRINTER_128.PNG" "note=" "UUID=cfe92100-67c4-11d4-a45f-dccd2f7b55e9" "adminurl=http://EPSON7B55E9.local.:80/PRESENTATION/BONJOUR" "usb_MFG=EPSON" "mopria-certified-scan=1.3" "duplex=T" "is=platen,adf" "cs=color,grayscale,binary" "pdl=application/pdf,image/jpeg" "ty=EPSON L6570 Series" "rs=eSCL" "vers=2.63" "txtvers=1"]
= enp7s0 IPv4 EPSON L6570 Series                            _scanner._tcp        local
   hostname = [EPSON7B55E9.local]
   address = [192.168.0.123]
   port = [1865]
   txt = ["note=" "scannerAvailable=1" "UUID=cfe92100-67c4-11d4-a45f-dccd2f7b55e9" "mdl=L6570 Series" "mfg=EPSON" "adminurl=http://EPSON7B55E9.local.:80/PRESENTATION/BONJOUR" "ty=EPSON L6570 Series" "txtvers=1"]
$ airscan-discover
[devices]
  EPSON L6570 Series = http://192.168.0.123:443/eSCL/, eSCL
  EPSON L6570 Series = http://192.168.0.123:80/WDP/SCAN, WSD

$ ippfind   # _ipp._tcp by default
ipp://EPSON7B55E9.local:631/ipp/print
$ ippfind _printer._tcp
lpd://EPSON7B55E9.local:515/auto
$ ipptool -tv ipp://EPSON7B55E9.local:631/ipp/print get-printer-attributes.test | grep -iE "printer attributes|ipp-versions"
    Get printer attributes using get-printer-attributes                  [PASS]
        ipp-versions-supported (1setOf keyword) = 1.0,1.1,2.0

$ lpinfo -l -v
Device: uri = dnssd://EPSON%20L6570%20Series._ipp._tcp.local/?uuid=cfe92100-67c4-11d4-a45f-dccd2f7b55e9
        class = network
        info = EPSON L6570 Series
        make-and-model = EPSON L6570 Series
        device-id = MFG:EPSON;MDL:L6570 Series;CMD:PWG,URF,JPEG;
        location = 
        NOTE Driver: IPP Everywhere
Device: uri = ipps://EPSON%20L6570%20Series._ipps._tcp.local/
        class = network
        info = EPSON L6570 Series (driverless)
        make-and-model = EPSON L6570 Series
        device-id = MFG:EPSON;MDL:L6570 Series;CMD:PWGRaster,AppleRaster,PWG,URF,JPEG;
        location = 
        NOTE Driver: IPP Everywhere (to same as for dnssd connection)
Device: uri = lpd://192.168.0.123:515/PASSTHRU
        class = network
        info = EPSON L6570 Series
        make-and-model = EPSON L6570 Series
        device-id = MFG:EPSON;CMD:ESCPL2,BDC,D4,D4PX,ESCPR7,END4,GENEP;MDL:L6570 Series;CLS:PRINTER;DES:EPSON L6570 Series;CID:EpsonRGB;FID:FXA,DPA,WFA,ETA,AFA,DAA,WRA;RID:41;DDS:022500;ELG:1380;SN:000000000000000000;
        location = 
        NOTE Driver: vendor proprietary or another suitable driver

Summarum

System
$ sudo dnf install avahi avahi-glib avahi-libs avahi-tools                       # Avahi
$ systemctl status avahi-daemon.service   # => active (running)

$ sudo firewall-cmd --permanent --add-service=mdns   # Multicast DNS on 5353 port
$ sudo firewall-cmd --reload

# CUPS and SANE work normally without Avahi (mDNS/DNS-SD).
# Avahi is used for device discovery and resolving mDNS '.local' hostnames.

$ avahi-resolve --address 172.30.0.55
172.30.0.55	BRW90324B17AD6E.local
$ avahi-resolve --name BRW90324B17AD6E.local
BRW90324B17AD6E.local	172.30.0.55
$ sudo dnf install sane-backends sane-backends-libs sane-airscan libsane-airscan # SANE AirScan

# disable 'v4l' (Webcams) devices at all
$ sudo cp -p --update=none /etc/sane.d/dll.conf /etc/sane.d/dll.conf.orig
$ sudo sed -i '/^v4l/s/^/#/' /etc/sane.d/dll.conf   # e.g. device v4l:/dev/video0
$ sudo dnf install cups cups-client cups-filesystem cups-filters cups-libs       # CUPS AirPrint
$ sudo dnf install cups-filters-driverless cups-ipptool
Find devices
$ avahi-browse --all --terminate | grep -iE 'printer|ipp|pdl|scan' # generic mDNS/DNS-SD
# finds printers/scanners via mDNS/DNS-SD (does not find WSD scanners)

$ ippfind                                                          # CUPS IPP (AirPrint)
# finds '_ipp(s)._tcp' and '_printer._tcp' mDNS/DNS-SD services (not '_pdl-datastream._tcp')

$ airscan-discover                                                 # SANE AirScan
# finds DNS-SD devices via Avahi and WSD devices via its own WS-Discovery implementation

$ lpinfo -v                                                        # CUPS list of available devices
$ scanimage -L                                                     # SANE list of available devices
Scanner

Na skenovanie v principe nie su potrebne ziadne nastavenia. scanimage sa pokusi otvorit prve dostupne zariadenie, co vsak moze byt problem v sieti s viacerymi zariadeniami. Vhodnejsie je pridat zariadenia do /etc/sane.d/airscan.conf v pozadovanom poradi, pripadne explicitne urcit default zariadenie nastavenim environment variable SANE_DEFAULT_DEVICE.

# /etc/sane.d/airscan.conf
[devices]
Brother MFC-T910DW = http://BRW90324B17AD6E.local:80/eSCL/, eSCL                       ; KE W47 (room 322)
Brother DCP-7070DW = http://BRN001BA9EBD873.local:80/WebServices/ScannerService, WSD   ; KE TN2

# Resolving '.local' names in WSL (Windows Subsystem for Linux) currently does not work, use direct IP addresses
Brother MFC-T910DW = http://192.168.0.175:80/eSCL/, eSCL    ; BJ K30
EPSON L6570 Series = http://192.168.0.123:443/eSCL/, eSCL   ; BJ K30
Printer
$ # lpadmin -p Brother_MFC-T910DW -L room322 -E -v "ipp://BRW90324B17AD6E.local:631/ipp/print" -m everywhere
$ lpadmin -p Brother_MFC_T910DW -E -v "ipp://BRW90324B17AD6E.local:631/ipp/print" -m everywhere
$ lpadmin -p HP_LaserJet_M611 -L caffe327 -E -v "ipp://10.0.0.23:631/ipp/print" -m everywhere

$ lpadmin -p Brother_DCP_7070DW -E -v "socket://BRN001BA9EBD873.local:9100" -m drv:///brlaser.drv/br7070d.ppd
# note01: 'ipp://BRN001BA9EBD873.local:631/duerqxesz5090' is "fake" IPP protocol (not working)
# note02: 'drv:///brlaser.drv/br7070d.ppd' provided by printer-driver-brlaserrpm package

Skenovanie

Windows vendor proprietarna aplikacia Brother ControlCenter4 (pre model MFC-T910DW) ponuka tieto typy skenovania:

  • Black & White, resp. Ciernobiele: pre textove obrazky alebo obrazky s ciarovou grafikou.
  • Grey (Error Diffusion), resp. Seda (chybovy rozptyl/prelinanie): grafika alebo fotografie. Dither (chybovy rozptyl/prelinanie) je metoda pre vytvaranie simulovanych sedych obrazkov bez pouzitia bodov pravej sedej. Cierne body sa ukladaju do urciteho vzoru, tak aby vytvorili iluziu sedej.
  • True Grey, resp. Prava seda/siva: grafika alebo fotografie. Tento rezim je presnejsi, kedze vytvara 256 odtienov sivej.
  • 24 Bit Colour, resp. Farebna 24 bitov: pouziva az 16.7 miliona farieb. Najvernejsia reprodukcia farieb, ale subor cca 3x vacsi ako pri 8 Bit Colour.

Windows vendor proprietarna aplikacia Epson Scan 2 (pre model L6570) ponuka analogicke typy skenovania: Black & White, Grayscale and Color.

Pozor na roznu terminologiu pri udavani farebneho formatu:

Vacsina skenerov v podstate umoznuje len dva typy skenovania: Grayscale (8-bit grayscale) a TrueColor (24-bit color). Vsetko ostatne software nasledne upravi do pozadovaneho typu, napr. do 1-bit monochrome alebo do 1-bit monochrome + dithering (simulacia sivych tonov pomocou bodkovanie). Z toho dovodu je vhodnejsie tento image post processing robit manualne, t.j. skenujeme do lossless formatu (napr. TIFF) a nasledne tento obrazok konvertujeme/upravujeme do nami pozadovaneho formatu. Takto ziskame podstatne vacsiu kontrolu a viac moznosti.

Ako uz bolo spomenute, skenery nevedia "fyzicky" skenovat 1-bit cierno-biele. Ak v options skenera aj existuje moznost Black & White (Lineart), tak interne sa skenuje v Grayscale a potom sa softwarovo (alebo firmware skenera) aplikuje (vacsinou velmi primitivne) "nejaky threshold" na vytvorenie 1-bit cierno-biele skenu.

Analogicky skener moze ponukat napr. option --scan-intent *unset*|Document|Text and Graphic|Photo|Preview [*unset*] (Optimize scan for Text/Photo/etc.), ktora zapina rozne interne (firmware) filtre skenera, ktore poskytuju vacsinou velmi primitivne a agresivne upravy. Nepouzivat, ponechat na default hodnote unset.

Vzdy skenujme len ako Color alebo Gray a cely post processing robime sami, zvycajne pomocou ImageMagick.

Grayscale skenovanie je cca o 40% – 50% rychlejsie ako Color (testovane na Brother MFC-T910DW a EPSON L6570). Grayscale skenovanie pracuje s vyrazne mensim objemom dat ako Color. Okrem toho, samotna skenovacia hlava sa moze v rezime Grayscale pohybovat rychlejsie, kedze nepotrebuje snimat rozne farebne vrstvy a nepotrebuje az tolko presnosti. Color skenovanie casto zahrna korekciu farieb, vyvazenie bielej, interpolaciu a podobne. Typ skenovanie Black & White je "len" software image post processing a rychlost samotneho skenovacieho procesu je identicka ako pre Grayscale.

$ time scanimage --device 'airscan:e0:Brother MFC-T910DW' --mode Color > scan.300dpi.color.pnm   # => 11.5s (default mode)
$ time scanimage --device 'airscan:e0:Brother MFC-T910DW' --mode Gray  > scan.300dpi.gray.pnm    # =>  6.5s

Ak planujem konvertovat na 1-bit monochrome (ciernobiely dokument) je vhodnejsie skenovat do Gray (a nie Color). V pripade ak mam k dispozicii uz len skor oskenovany farebny dokument, tak ho najprv konvertovat na Gray a az potom na 1-bit monochrome.

# ChatGPT
convert scan.pnm -threshold 50% scan_bw.png
--resolution 300 (pre text), pripadne --resolution 400 pre mensie pismo
convert gray.pnm -blur 0x1 -threshold 55% bw.png   # lepsie vysledky potlacenie sumu
convert gray.pnm -auto-threshold OTSU bw.png   # OTSU najvhodnejsi na dokumenty
                 -auto-threshold Triangle
                 -auto-threshold Kapur
convert gray.pnm -dither FloydSteinberg -colors 2 bw.png   # vhodny na obrazky, nie na dokumenty !!!
scanimage --mode Gray --resolution 300 | convert - -auto-threshold OTSU -type bilevel scan_bw.png
scanimage --mode Gray --resolution 300 | convert - -auto-level -auto-threshold OTSU clean.png

convert -monochrome # takto nie, velmi jednoduche, v principe: -colorspace Gray -threshold 50%

PostProcessing 2
See also [1].

$ tesseract output.tiff output_text -l slk pdf
$ ocrmypdf -l slk dokument_bez_ocr.pdf dokument_ocr.pdf
* https://github.com/unpaper/unpaper/blob/main/doc/basic-concepts.md
* https://paperless.readthedocs.io (dead project, last release 2019-01)
* https://docs.paperless-ngx.com/   (successor to the original Paperless & Paperless-ng)

na archivaciu asi JPEG XL
https://www.root.cz/n/jpeg-xl/
https://www.root.cz/clanky/ani-heic-ani-avif-ale-jpeg-xl-bude-nastupcem-stareho-jpegu/
https://www.root.cz/zpravicky/schvaleno-pro-fedoru-43-nova-verze-rpm-6-0-ci-jpeg-xl-wallpapery/
https://www.root.cz/zpravicky/ubuntu-25-04-s-podporou-jpeg-xl/

PostProcessing 3
Profesionalne skenery/programy (napr. ABBYY FineReader)udajne umoznuje oddelit v beznych dokumentoch:

  • textovu cierno bielu cast (1-bit G4)
  • a farebny zbytok, napr. peciatka, podpis (RGB ZIP alebo JPEG)

Tieto dve vrstvy sa potom spoja do vysledneho obrazku TIFF MRC (Mixed Raster Content), see also [2]. LibTIFF ani ImageMagick to neumoznuje ?! Pod Linux pravdepodobne existuje len tento jediny projekt Internet Archive PDF Tools.

Brother ControlCenter4 (v4.6.46.1, released 2021-11) Epson Scan 2 (v6.7.45.0, released 2024-06)

summary

$ scanimage --mode Gray --format tiff > scan.300dpi.gray.tiff
$ magick scan.300dpi.gray.tiff -auto-threshold OTSU -compress Group4 scan.300dpi.tiff   # or try threshold 50―75%
$ ocrmypdf -l slk scan.300dpi.tiff scan.300dpi.pdf    # !!!!!! OCR robit na Gray nie na 1-bit monochrome
$ magick exam1.tiff -colorspace Gray -auto-threshold OTSU -depth 1 -compress none exam1.mono1.tiff # color to 1-bit monochrome

TIFF

# Fedora libtiffrpm subpackages
$ dnf install libtiff libtiff-tools

Na pracu s TIFF image file format sa siroko pouziva kniznica LibTIFF, takze dalej budeme uvazovat o moznostiach, ktore nam poskytuje prave tato kniznica LibTIFF Coverage of the TIFF 6.0 Specification. ImageMagick pre pracu s TIFF pouziva LibTIFF ako externu kniznicu.

$ magick -list format | grep -i libtiff
   TIFF* TIFF      rw+   Tagged Image File Format (LIBTIFF, Version 4.7.2)
 TIFF64* TIFF      rw+   Tagged Image File Format (64-bit) (LIBTIFF, Version 4.7.2)

NOTE LibTIFF vo verzii 4.6.0 (released 2023-09) prestal podporovat niektore tools, udajne z dovodu nedostatku udrzby. Jedine zostavajuce a podporovane nastroje boli: tiffinfo(1), tiffdump(1), tiffcp(1) a tiffset(1). Po velkej vlne kritiky sa s vydanim verzie 4.7.0 (released 2024-09) vsetky TIFF Tools vratili naspat.

# Building Fedora libtiff.spec packages (tiff-4.7.2, released 2026-07) and support for compression programs (codecs)
#
# installed packages:   | zlib-devel | libjpeg-devel | jbigkit-devel | liblerc-devel | libzstd-devel | libwebp-devel |
# tiff external codecs: | -c zip:s0  | -c jpeg       | -c jbig       | -c lerc       | -c zstd       | -c webp       |
# not installed packages: | libdeflate-devel | xz-devel |
# tiff external codecs:   | -c zip:s1        | -c lzma  |
# obsolete package names on Fedora: zlib-devel => zlib-ng-compat-devel and libjpeg-devel => libjpeg-turbo-devel

# https://libtiff.gitlab.io/libtiff/build.html
[tiff-4.7.2]$ ./configure
Support for internal codecs:
 CCITT Group 3 & 4 algorithms:       yes   # -c g3, -c g4
 Macintosh PackBits algorithm:       yes   # -c packbits
 LZW algorithm:                      yes   # -c lzw
 ThunderScan 4-bit RLE algorithm:    yes   # decoding only
 NeXT 2-bit RLE algorithm:           yes   # decoding only
 LogLuv high dynamic range encoding: yes   # -c sgilog

Support for external codecs:
 ZLIB support:                       yes   # zlib-devel       # ZIP_SUPPORT        (-c zip:s0)
 libdeflate support:                 no    # libdeflate-devel # LIBDEFLATE_SUPPORT (-c zip:s1)
 Pixar log-format algorithm:         yes   # zlib-devel
 JPEG support:                       yes   # libjpeg-devel
 Old JPEG support:                   yes   # libjpeg-devel
 JPEG 8/12 bit dual mode:            yes   # libjpeg-devel (libjpeg turbo >= 3.0 dual mode)
 ISO JBIG support:                   yes   # jbigkit-devel    # (JBIG1, not JBIG2)
 LERC support:                       yes   # liblerc-devel
 LZMA2 support:                      no    # xz-devel
 ZSTD support:                       yes   # libzstd-devel
 WEBP support:                       yes   # libwebp-devel
# tiffcp(1) from Fedora package libtiff-toolsrpm with ZIP_SUPPORT (zlib) and without LIBDEFLATE_SUPPORT (deflate)
$ tiffcp -c zip    in.tiff out.tiff   # zlib (by default)      # identical as -c zip:s0
$ tiffinfo out.tiff | grep -i compress
 Compression Scheme: AdobeDeflate
$ tiffcp -c zip:s1 in.tiff out.tiff   # deflate
ZIPVSetField: DeflateCodec = DEFLATE_SUBCODEC_LIBDEFLATE unsupported in this build.

# custom build of LibTIFF with ZIP_SUPPORT (zlib) and with LIBDEFLATE_SUPPORT (deflate) together
$ tiffcp -c zip    in.tiff out.tiff   # deflate (by default)   # identical as -c zip:s1
$ tiffinfo out.tiff | grep -i compress
 Compression Scheme: AdobeDeflate
$ tiffcp -c zip:s0 in.tiff out.tiff   # zlib
$ tiffinfo out.tiff | grep -i compress
 Compression Scheme: AdobeDeflate

NOTE In both cases compression scheme always as 'AdobeDeflate'. Personally, I consider this to be an unsuitable solution that only creates unnecessary confusion.

LIBDEFLATE_SUPPORT -c zip:s1 by default dava o nieco lepsiu kompresiu ako ZIP_SUPPORT -c zip:s0, ale pri pouziti odporucanej option -r -1 su vysledky identicke, takze sa straca zmysel aky deflate/zip algoritmus pouzit.
# scan 300dpi image (A4 paper) original size 26828790 bytes
./tiffcp -c zip:s0               8169294      -c zip:s1               7755098
./tiffcp -c zip:s0 -r -1         5941114      -c zip:s1 -r -1         5941114
./tiffcp -c zip:s0:2:p12 -r -1   4561472      -c zip:s1:2:p12 -r -1   4561472
LibTIFF lossless compression
-c none no compression algorithm
-c lzw:# Lempel-Ziv & Welch encoding najstarsi a siroko pouzivany standard
-c zip:#:p# deflate (zlib) encoding, gz novsia a lepsia kompresia ako lzw (TIFF 6.0 extension)
-c zstd:#:p# ZSTD encoding (facebook) vylepsena kompresia, ale problematicke podpora v roznych programoch
-c lzma:#:p# LZMA2 encoding (disable on Fedora LibTIFF), xz najsilnejsia kompresia, ale problematicke podpora v roznych programoch
-c g4 CCITT Group 4 fax encoding odporucana a efektivna kompresia, ale iba pre 1-bit monochrome

Ostane (nevhodne) lossless compressions: -c packbits najslabsia kompresia, -c webp (lossless) problematicka podpora; 1-bit monochrome compressions: -c jbig (JBIG1) problematicka podpora, -c g3 slabsia kompresia ako -c g4.

Pre lossy compression sa pre bezproblemovost vseobecne odporuca -c jpeg, pripadne -c webp (lossy) ale s problematickou podporou.

LibTIFF obsahuje podporu aj pre specificke compressions: -c sgilog (LogLuv high dynamic range encoding) a -c lerc (ESRI LERC).


Miera efektivity lossless kompresie nezavisi len od pouzitia co najefektivnejsieho komprimacneho algoritmu, ale znacne aj od pred-pripravy dat (write output in strips or tiles) na samotnu kompresiu. Okrem toho plati, cim obrazok obsahuje viac "hluchych (rovnakych) pixelov", tym bude lossless kompresie efektivnejsia. Preto vo vseobecnosti je efektivita lossless kompresie pre skenovany dokument znacne lepsia ako pre skenovanu fotografiu.

NOTE Tool tiffcp(1) (ale nie ostatne LibTIFF tools) umoznuje nastavit compression level for lossless codecs az od LibTIFF verzii 4.7.1 (released 2025-09). Preset number p# set compression level (zip, zstd, lzma).
-c zip:p# umoznuje nastavit compression level od p1 az do p12 pre LIBDEFLATE_SUPPORT (deflate, -c zip:s1:p#). Identicky aj v pripade ZIP_SUPPORT (zlib, -c zip:s0:p#), ale max. hodnota je p9 (hodnoty medzi p9 az p12 sa interpretuju ako max. compression level, t.j. ako p9). Default hodnota je p6, resp. p-1.



Rotacia nie len cez "tiffcrop -R 90", ale aj cez "$ tiffset -s 274 1 exam1.tiff", ale ake su mozne hodnoty pre Orientation (274) tag ?!

Preferovat tiffcrop -R 90, ten realne otoci obrazok, a tag 274 bude vzdy =1

"Support for orientations other than 1 is not a Baseline TIFF requirement." (https://download.osgeo.org/libtiff/doc/TIFF6.pdf)

strips (pruhy) / tiles (dlazdice)

Data v TIFF subore mozu byt usporiadane ako strips (option -s) alebo ako tiles (option -t). tiffcp(1) default-ne ako strips.

  • Option -r (implies -s option) specifikuje pocet riadkov pre kazdy strip. Default hodnota -r 0 znamena, ze tiffcp(1) automaticky nastavi hodnotu poctu riadkov pre strip tak, aby velkost strip-u nebola vacsia ako 8 kB (zvyacjne na RowsPerStrip = 1). Specialna hodnota -r -1 (infinite number of the rows per strip) znamena, ze cely obrazok bude ako jeden velky strip a vysledna prislusna hodnota RowsPerStrip sa vypocita.
  • Options -w resp. -l (implies -t option) specifikuju sirku resp. dlzku dlazdice v pixeloch. tiffcp(1) nevytvori dlazdicu, ktorej velkost moze byt vacsia ako 8 kB (zvycajne na TileWidth = 256 resp. TileLength = 256).

Tiles su vo vseobecnosti vhodnejsie pre vacsie (10 – 100 megapixelov) obrazky, napr. satelitne alebo ortofoto snimky, kedy sa v podstate jeden velky mega obrazok, rozkuskuje na mensie dlazdice. Pre mensie obrazky, napr. skenovane dokumenty (A4 format, 300dpi = cca 9 megapixelov) je vhodnejsie pouzivat strips.


JBIG2

JBIG2 is an image compression standard for 1-bit monochrome images. Je primarne navrhnuty pre kompresiu cierno-bielych skenovanych dokumentov do PDF (kompresna schema velmi podobna DjVu). Podporuje lossless aj lossy kompresiu. V lossless mode JBIG2 moze udajne generovat subory 3–5x mensie ako G4 (CCITT Group 4) compression. Je tu vsak niekolko podstatnych ale:

From jbig2enc doc: Most input images to JBIG2 encoders are scanned text. These have many repeating symbols (letters). The idea of symbol encoding is to encode what a letter 'a' looks like and, for all the 'a's on the page, just give their locations. This is lossy encoding (-s --symbol-mode).

Nie je prilis jasne ako dosiahnut lossless kompresiu. Udajne su dve moznosti, 1st) bez option --symbol-mode alebo 2nd) kombinaciou options --refine a --symbol-mode, ale potom problem:

$ ./jbig2 --refine --symbol-mode
Refinement broke in recent releases since it's rarely used. If you need it you should bug agl@imperialviolet.org to fix it

Summa summarum: aj ked JBIG2 dnes umoznuje najlepsiu lossless kompresiu pre 1-bit monochrome images, uprednostnovat bezproblemovu CCITT Group 4 (G4) kompresiu. Pouzivanie JBIG2 spolu s OCRmyPDF by vsak malo byt bez problemov.

binary images = bitonal images = bi-level images = 1-bit monochrome images = 1 bpp (bit per pixel) images = "black & white"