Orfeus: a RAW processor for Olympus PEN-F and OM-1
A fast Common Lisp RAW processor for Olympus PEN-F and OM-1 files. The same processing core drives a command-line tool and an FLTK GUI, so a batch export and an interactive grade always render identically.
Grading as a node graph, not a slider panel you hope you remember.
- Cameras
- Olympus PEN-F and OM-1 ORF, embedded in DNG
- Frontends
- CLI and FLTK GUI over one processing core
- Batch format
- Readable, editable S-expression projects
- Grading
- DaVinci-style node graph, scene-linear blends
- GPU path
- Optional Vulkan compute, CPU fallback on failure
- License
- COLL-Attribution
- Repository
- luciusmagn/orfeus
One core, two frontends
The command line and the GUI call the same Common Lisp processing core, so a photo renders identically whether it came from an interactive grade or an unattended batch run. A native Rust bridge handles RAW decode and pixel work; Orfeus orchestrates it and owns every decision about what happens to a photo.
Olympus stores the original ORF embedded inside the DNG its own tools produce. Orfeus can inspect or pull that original back out before it does anything else with a photograph.
$ orfeus info photograph.dng
$ orfeus extract photograph.dng photograph.orf
$ orfeus preview photograph.orf preview.jpg
$ orfeus render photograph.orf export.tiff
$ orfeus init project.sexp exports/ first.orf second.orf
$ orfeus batch project.sexp
Grading as a node graph
A photo's grade is an explicit, piped node graph, not a single
flat settings panel. Node kinds carry one adjustment category
each, including repeated kinds, so two +2 EV
exposure nodes make +4. Nodes are reorderable and
individually bypassable, and maskless blend nodes mix two
scene-linear branches by opacity.
A dedicated :color-subtract node inverts a film
negative by subtracting the picked base color from each
pixel in scene-linear space, with palette and eyedropper
pickers in the GUI. Crop nodes carry a resolution-independent
oriented rectangle, so one graph fits both a fast preview and
a full-resolution export, and a negative-autocrop mode
detects the frame and film-base color on its own.
Photographs without a graph keep the flat, five-stage pipeline unchanged; both paths render through the same batch runner. The GUI grabs auto-named stills into a thumbnail gallery, and right-clicking one applies its whole node graph to the current selection, optionally without its lens profile or white balance.
;; excerpt: the :graph value inside one :photos entry
(:graph
(:nodes ((:id 1 :kind :exposure
:inputs (0) :params (:exposure 2.0))
(:id 2 :kind :exposure
:inputs (1) :params (:exposure 2.0))
(:id 3 :kind :color-subtract
:inputs (2)
:params (:red 0.92 :green 0.85 :blue 0.71)))
:output 3))
Optics and film
Lens correction matches Lensfun profiles from a photo's own EXIF automatically. Adapted manual lenses can be mapped to an exact Lensfun profile with a focal reducer ratio and crop factor, so a speed-boosted vintage lens still gets correct geometry and vignetting instead of no correction at all.
The bundled film-emulation LUT library ships Agfa APX,
Precisa, and Ultra Color looks alongside Kodachrome 25, 64,
64 Generic, and 200, with provenance and checksums recorded
in the repository's THIRD-PARTY.md.
(("Ultron 0.7x"
:lensfun-model "Voigtlander Ultron 40mm f/2 SLII Aspherical"
:focal-reducer 0.71
:crop-factor 2.0))
Batch projects are read with *read-eval* disabled,
so opening someone else's project file cannot run arbitrary
code. An optional Vulkan compute backend fuses display tone and
the sRGB transfer curve; it stays opt-in behind
ORFEUS_GPU=1 because one-shot Vulkan initialization
is expensive, and any initialization, dispatch, or readback
failure falls back to the CPU result automatically.
Build from source
Orfeus targets Linux and has no packaged binary yet. The Nix
flake provides SBCL, Rust, the LibRaw and Lensfun native
dependencies, ExifTool, JPEG and TIFF support, and FLTK. Keep
a sibling lightfast
checkout available when building the GUI.
There is no nix build package output yet, only
a development shell. Enter it, then build the native bridge,
the GUI, and the Lisp system in order.
Enter the environment
$ nix develop
Build the native bridge and GUI
$ cargo build --release --manifest-path native/Cargo.toml
$ make gui-native
Build the CLI
$ sbcl --no-userinit --non-interactive \
--eval '(require :asdf)' \
--eval '(asdf:load-asd (truename "orfeus.asd"))' \
--eval '(asdf:make "orfeus/cli")'
Run it
$ ./orfeus info photograph.dng
$ ./orfeus-gui