diff options
Diffstat (limited to 'docs/gegl.md')
| -rw-r--r-- | docs/gegl.md | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/docs/gegl.md b/docs/gegl.md new file mode 100644 index 0000000..0fe54d5 --- /dev/null +++ b/docs/gegl.md @@ -0,0 +1,150 @@ +# GEGL Integration + +GEGL (Generic Graphics Library) — the data-flow, floating-point, +non-destructive image-processing framework behind GIMP, GNOME Photos, imgflo, +and iconographer. You chain *operations* (ops) into a graph; GEGL renders it. +Full op list: <https://gegl.org/operations/>. + +ggaze uses GEGL for **quick, non-destructive photo enhance** plus a few bonus +capabilities. It is an **optional** dependency (meson `feature`); a minimal +build skips it and ggaze stays a plain fast viewer. + +## Scope stance + +ggaze is a *culling viewer*, not an editor. GEGL enhance is **opt-in and +non-destructive**: a preset is applied as a live preview to help judge a +keeper, and can be exported as a **copy** (the original file is never +modified). No layers, masks, undo stacks, or sidecar `.gegl` state. Full +editing remains a non-goal. + +## The quick-enhance feature + +- `a` → **enhance popup** (same popover pattern as `m`/`e`/`!`): lists presets, + each with an auto-assigned hotkey (`1`, `2`, … then `0`, `a`-`z`). +- Selecting a preset applies a **GEGL graph** to the current image and + re-renders the viewer through it — non-destructively. Press it again (or + `Esc`) to turn the preview off. +- `s` (or menu *Save enhanced copy…*) writes the enhanced result to a + new file, e.g. `IMG_0001-enhanced.jpg`, via a GEGL saver. Original untouched. + ggaze **never auto-saves** — the preview is a live overlay only. Moving to + another image (or quitting) with an un-exported preview prompts + Save/Discard/Cancel; `s` saves and clears dirty, `Esc`/re-press discards. +- Export format: defaults to the original extension (JPEG quality 95); a + format/quality chooser and a lossless `jpegtran`/`exiftool` path are later. +- Presets are configurable: `enhance-presets` GSettings `a(ss)` — ordered + `(name, gegl-graph)` pairs. Order = hotkey order. Ships with sensible + built-in defaults; user can add/edit in Preferences (`,`). +- GEGL runs **only** when a preset is active or on export. The default fast + decode path (GdkPixbuf / direct libs) is unchanged — the "fast" goal holds. +- Enhance is **not** applied during `h`/`l` scrubbing — only when settled on an + image — so flipping stays instant. + +### Built-in preset ideas (real GEGL ops) + +Defaults ship with the first ~12; the rest are optional/artistic. Each is a +one-shot GEGL graph applied as a non-destructive preview (`a` popup, `s` to +save a copy). + +| Preset | Graph (ops) | +|---------------|-------------------------------------------------------------| +| Auto-fix | `gegl:stretch-contrast` → `gegl:color-enhance` | +| Brightness | `gegl:exposure` (or `gegl:brightness-contrast` brightness) | +| Contrast | `gegl:brightness-contrast` (contrast +) | +| Saturation | `gegl:saturation` (or `gegl:color-enhance`) | +| Warm | `gegl:color-temperature` (warmer) | +| Cool | `gegl:color-temperature` (cooler) | +| White balance | `gegl:color-enhance` → `gegl:stretch-contrast` | +| Shadows | `gegl:shadows-highlights` (lift shadows) | +| Highlights | `gegl:shadows-highlights` (recover highlights) | +| Levels | `gegl:levels` | +| Curves | `gegl:contrast-curve` (gentle S-curve) / `gegl:curve` | +| Sharpen | `gegl:sharpen` (unsharp mask) | +| Denoise | `gegl:noise-reduction` (or `gegl:bilateral-filter`) | +| Clarity | `gegl:high-pass-filter` blend (local contrast) | +| Grayscale | `gegl:color-to-grayscale` (or `gegl:mono-mixer`) | +| Sepia | `gegl:sepia` | +| Vignette | `gegl:vignette` | +| Softglow | `gegl:softglow` | + +**Tunable parameters:** every preset is a `gegl-graph` string in +`enhance-presets` (`a(ss)`), so the exact strength (saturation amount, +contrast level, exposure stops) is editable in Preferences or via +`gsettings` — no slider UI needed. The Curves preset uses a fixed curve shape +(also editable in the graph text); a full interactive curve editor is out of +scope — hand off to GIMP (`e`) for that. A later "fine adjust" mode could +expose ± nudging of the active preset's main parameter. + +Graph strings are illustrative. Built-in presets are built programmatically +with `gegl_node_new_child`; user-authored presets can be stored as `gegl:gegl` +graph text and parsed with `gegl_node_new_from_xml`. + +## Crop, straighten & rotate tools + +Same non-destructive model as enhance (live preview graph + `s` to export a +copy), but interactive (crop/straighten) or one-shot (rotate): + +- **`c` — crop** (`gegl:crop`): adjustable rectangle; aspect-ratio presets; + mouse drag or keyboard (`h`/`l`/`j`/`k` move, `H`/`L`/`J`/`K` resize); `Enter` + apply. +- **`R` — straighten** (`gegl:rotate`): drag a horizon line or nudge the + angle (`h`/`l`, ±0.5°) with a grid overlay; optional auto-crop of rotated + corners; `Enter` apply. +- **`[` / `]` — rotate 90°** (`gegl:rotate-on-center`): one-shot CCW/CW; repeat + for 180°/270°. No overlay. +- Compose with enhance presets in the same graph. Large view only; GEGL + required. + +## Module + +`enhancer.{c,h}` → `Enhancer` (+ `EnhancerPreset`). Plain-C, no GtkWidget, +unit-testable. Runs GEGL in a `GTask` thread (off the UI thread). + +```c +EnhancerPreset *enhancer_get_presets(void); /* from GSettings */ +GeglBuffer *enhancer_apply(GeglBuffer *p_in, EnhancerPreset *p, GError **); +gboolean enhancer_export(GeglBuffer *p_in, EnhancerPreset *p, + GFile *p_out, GError **); +``` + +Viewer integration: when a preset is active, the decoded pixels are imported +into a `GeglBuffer` (GEGL GdkPixbuf-source op / babl), the enhancer processes +it, and the output buffer is rendered back to a `GdkTexture` for display. +This path is heavier, so it is strictly on-demand. + +## What else GEGL gives ggaze + +- **Color management** — `gegl:icc-file-loader`, `gegl:lcms-from-profile`, + `gegl:cast-color-space`, `gegl:convert-color-space`, plus ICC-aware savers. + Closes open question **G** (color management) via babl + LCMS, no separate + wiring. +- **Format load/save** — `gegl:jpg-load`/`-save`, `gegl:png-load`/`-save`, + `gegl:tiff-load`/`-save`, `gegl:webp-load`/`-save`, `gegl:ppm-*`, + `gegl:rgbe-*`, `gegl:gegl-buffer-load`/`-save`. Can augment GdkPixbuf on the + enhance/export path (JXL/AVIF/HEIF still need their own libs). +- **Thumbnail generation** — `gegl:load` → `gegl:scale-size` → save; an + alternative backend for the thumbnail cache. +- **Transforms** — **crop** (`gegl:crop`), **straighten** (`gegl:rotate`) and + **rotate 90°** (`gegl:rotate-on-center`) are in scope as tools + (`c`/`R`/`[`/`]`); lens correction (`gegl:lens-distortion`), red-eye + (`gegl:red-eye-removal`), and `gegl:scale-ratio` remain later/maybe. +- **Tone mapping** — `gegl:reinhard-2005`, `gegl:mantiuk-2006`, + `gegl:fattal-2002` (handy for linear/HDR-ish scenes). +- **Artistic** (optional/fun) — `gegl:vignette`, `gegl:sepia`, `gegl:softglow`, + `gegl:oilify`, `gegl:cartoon`, `gegl:photocopy`. +- **Batch** — drive the `gegl` CLI via the `!` runner for bulk enhance/export + without building it into ggaze's UI. + +## Costs & trade-offs + +- Heavier deps: `gegl`, `babl` (and transitively more). Gate behind a meson + `feature` so minimal builds and the core culling flow don't pay for it. +- GEGL processing is slower than straight decode — keep it off the hot path. +- `gegl-gtk` (GeglGtkView) is separate and thinly maintained — **avoid**; keep + the custom `GgazeViewer` widget and render GEGL output to `GdkTexture`. +- GEGL does **not** demosaic RAW — RAW stays out of scope. + +## Dependencies (Fedora) + +``` +gegl-devel babl-devel +```
\ No newline at end of file |
