5 4. Architecture
Ben Olden-Cooligan edited this page 2023-01-14 17:53:09 -08:00

Note that, as always, design documentation is a high-level overview and may simplify some things. The source of truth is the code itself. Have a look at the relevant classes and any comments they have for additional details.

Scan Pipeline

The NAPS2 scanning architecture is fairly complicated as it needs to support multiple platforms, process architectures, and driver types, while efficiently performing various kinds of processing. Core scanning functionality lives in NAPS2.Sdk while functionality specific to the NAPS2 desktop app is in NAPS2.Lib.

  • ScanPerformer - This contains business logic for the NAPS2 desktop application. It converts ScanProfile (user profile settings) + ScanParams (contextual settings) into ScanOptions, prompts for a device if needed, does Auto Save, records scan events, etc.
  • ScanController - This is the entry point for scanning in NAPS2.Sdk, and encompasses all core scanning functionality.
  • InProcScanBridge/WorkerScanBridge - Abstracts communication as either in-process or with a worker process, chosen by the logic in ScanBridgeFactory. (At one point NetworkScanBridge was also part of this design, but that's been superseded by ESCL, which is an open standard for network scanning.)
  • RemoteScanController - Does the actual scanning operation, possibly inside a worker process.
  • LocalPostProcessor - This currently only does OCR, which is a long running operation that is owned by the calling process.
  • RemotePostProcessor - This does most post-processing (e.g. thumbnail generation, auto deskew, etc.). It is done in the scanning process, which is more efficient as we already have the image in memory.

1 Note that images (aside from thumbnails) are stored on the filesystem, not transferred across the pipe.
2 When using 32-bit TWAIN (the default) from a 64-bit process, the ITwainSesssionController abstraction also does IPC. This is used instead of WorkerScanBridge so that, when using TwainTransferMode.Memory for incremental transfer, the TwainScanDriver process building the image can operate in 64-bit mode and avoid out-of-memory errors for large images.
3 The intention is for the SANE native wrapper to live in the NAPS2.Sane package eventually, but currently it's just in the NAPS2.Scan.Internal.Sane.Native namespace in NAPS2.Sdk.
4 ESCL can also operate over USB, although on Windows this requires a particular driver to be installed.
5 When using TwainDsm.Old, this is twain_32.dll instead.
6 On Mac this is libsane.dylib.