Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
b08b928
wb: added new param late_correction to temperature.c, exposed as a ch…
kofa73 Dec 10, 2025
f7b4813
wb: Updated the rest of the files, but channelmixerrgb is broken, eve…
kofa73 Dec 16, 2025
f2786ae
wb: Undid changes to channelmixerrgb.c, will go carefully next time
kofa73 Dec 16, 2025
25dcb6f
wb: Fixed publishing of late_correction in temperature.c
kofa73 Dec 17, 2025
1e7cc36
wb: added DT_ILLUMINANT_FROM_WB, separated find_temperature_from_raw_…
kofa73 Dec 17, 2025
c25ec3a
wb: fix switch-case fall-through in illuminants.h#illuminant_to_xy; v…
kofa73 Feb 28, 2026
19e361c
wb: safe division in _get_d65_correction_ratios
kofa73 Feb 28, 2026
11d9d31
wb: added _get_corrected_illuminant_xy to deduplicate repeated code
kofa73 Feb 28, 2026
dd450a4
wb: fix illuminants.h switch-case fall-through introduced when DT_ILL…
kofa73 Mar 6, 2026
5f8a0c8
wb: renamed find_temperature_from_... to find_illuminant_xy_from_...;…
kofa73 Apr 5, 2026
6981e62
Doc updates
kofa73 May 31, 2026
cd2f446
Doc updates: wb + color calibration
kofa73 May 31, 2026
5baae49
wb: removed 'as-shot to reference' (same as 'as shot' + 'prepare data…
kofa73 May 31, 2026
7f51e3a
wb: make sure color calibration / white balance warning is shown when…
kofa73 Jun 6, 2026
051e6e2
wb: don't modify p->x, p->y in _preview_pipe_finished_callback; switc…
kofa73 Jun 7, 2026
c24c307
wb: minor clean-up in channelmixerrgb (GUI struct field names for cla…
kofa73 Jun 7, 2026
a10e8e0
wb: opposed.c hash: late_correction is a param of temperature (is bef…
kofa73 Jun 7, 2026
ff4c93f
wb: tiny clean-up: unnecessary parens, accidental duplication
kofa73 Jun 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion dev-doc/IOP_Module_API.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ This guide documents the functions that darktable Image Operation (IOP) modules

See also:
- [Pixelpipe Architecture](pixelpipe_architecture.md) for pipeline data flow and caching.
- [Module Lifecycle](Module_Lifecycle.md) for when these callbacks fire and what the system does around them.
- [Introspection System](introspection.md) for parameter management.
- [GUI Architecture](GUI.md) for GUI events, callbacks, thread safety, and widget reparenting.

Expand Down Expand Up @@ -360,7 +361,13 @@ Access in `process_cl()` via `self->global_data`.

### `reload_defaults()` - Per-Image Defaults

Called when switching images. Update defaults based on image properties:
Called when switching images (and on first load). Its purpose is to make `self->default_params` image-specific — most modules have defaults that depend on whether the image is RAW, HDR, monochrome, etc., and those cannot be compile-time constants.

When invoked through the wrapper `dt_iop_reload_defaults()`, the harness calls `dt_iop_load_default_params()` after the module's own `reload_defaults()` returns, copying `default_params` into `self->params`. So on the wrapper path, writing to `default_params` inside `reload_defaults()` immediately affects `self->params` as well. Most callers use the wrapper (e.g. `_dt_dev_load_pipeline_defaults()`, the per-module Reset button, instance duplication).

**Caveat — direct calls bypass only the framework copy, not the module body.** A few sites invoke `module->reload_defaults(module)` directly instead of through the wrapper (for example `develop.c` calls `temperature->reload_defaults(temperature)` to refresh WB side-effects). Those callers do **not** get the automatic `dt_iop_load_default_params()`, so the wholesale `default_params → self->params` copy does not happen. This does **not** mean `self->params` is left untouched: the module's own `reload_defaults()` body may still write specific `self->params` fields directly. `temperature.reload_defaults()` does exactly this — it writes `p->preset` and `p->late_correction` (via `p = self->params`) in lockstep with `default_params`, while the WB coefficient array is written to `default_params` only. On a direct call, the result is therefore a *partial* update: the fields the body touches change in `self->params`, the rest do not, and no history entry is recorded. If you add such a call, prefer `dt_iop_reload_defaults()`, or audit exactly which `self->params` fields the body mutates and sync the rest yourself.

#### Job 1 (all modules that implement this): compute image-specific default params

```c
void reload_defaults(dt_iop_module_t *self)
Expand All @@ -373,8 +380,31 @@ void reload_defaults(dt_iop_module_t *self)
}
```

Example: `exposure.c` disables itself for non-RAW images by setting `self->default_enabled = FALSE`. The exposure value in `default_params` stays at its static value because exposure is image-type-agnostic beyond that flag.

Common checks: `dt_image_is_raw()`, `dt_image_is_hdr()`, `dt_image_is_ldr()`, `dt_image_is_monochrome()`, `dt_image_is_bayerRGB()`.

#### Job 2 (some modules): write shared inter-module data as a side effect

Some modules use `reload_defaults()` to populate shared state in `dev->chroma` (or similar structures) that other modules depend on. This happens regardless of whether the module is enabled or has a history entry.

Example: `temperature.c` always computes the camera's as-shot WB coefficients and D65 reference coefficients from the image's EXIF data and writes them into `dev->chroma.as_shot[]` and `dev->chroma.D65coeffs[]`. `channelmixerrgb.c` reads these values during its own `commit_params()` to perform chromatic adaptation. If `reload_defaults()` did not run unconditionally, `channelmixerrgb` would have no access to the camera's native WB — even when the white balance module itself is disabled or absent from the history.

For the complete producer/consumer map, the reverse-order default-loading reasoning, and which `dev->chroma` fields each module actually reads, see [iop/wb_and_colorcalibration](iop/wb_and_colorcalibration/README.md).

#### Where `default_params` is consumed

**Initial image load.** Inside `dt_dev_read_history_ext()`, `_dt_dev_load_pipeline_defaults()` calls `reload_defaults()` for every module (in reverse pipe order) and copies each `default_params` into `params`. The function then adds the workflow default modules and any auto-presets, and builds `dev->history` **directly from the database rows** — it does *not* call `dt_dev_pop_history_items`. A module with a history row runs with the saved params from that row; a module without one keeps the image-specific `default_params` just loaded. This is true on both the first open of an image and the reopen of an edited one; the only difference is whether the database has any rows for that module.

**Undo / redo / history-panel navigation.** This is the separate path that uses `dt_dev_pop_history_items_ext()`, which does two passes:

1. Resets all modules: `module->params = module->default_params` — so modules absent from the replayed range start from their image-specific default, not garbage.
2. Replays history entries: `module->params = hist->params` for each entry up to the target position.

So `default_params` is consumed in two ways: as the starting point for modules with no (or not-yet-replayed) history, and as the value the per-module "Reset to defaults" button restores. It also sets the visual "default" markers on GUI sliders (via `dt_bauhaus_slider_set_default()`).

For the full sequence — load order, the `dev->chroma` side effects, and the reverse-iteration hazard — see [Module_Lifecycle.md](Module_Lifecycle.md).

### Pipe Lifecycle Functions

Each pixelpipe has its own copy of every module's data via `dt_dev_pixelpipe_iop_t` ("piece").
Expand Down
2 changes: 1 addition & 1 deletion dev-doc/Module_Groups.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Darktable uses a tabs-based interface in the right panel. Each tab corresponds t
- **Technical**: Basic corrections (demosaic, lens, crop).
- **Grading**: Color and tone grading.
- **Effects**: Artistic effects.
- **Quick Access Panel**: (Special case, detailed in `Quick_Access_Panel.md`).
- **Quick Access Panel**: (Special case, detailed in [Quick_Access_Panel.md](Quick_Access_Panel.md)).

## Implementation (`modulegroups.c`)

Expand Down
Loading
Loading