darktable-org / darktable-org/darktable
Exposure area mapping ignores black correction
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 13.1k
- Forks
- 1.4k
- Avg merge
- 22h 14m
- Merged PRs (30d)
- 198
Description
Severity: medium. Pre-existing at
d63f1023a3ca8db0c192c902e2d2151a161b6dac, still present at
11093f0767b118d8f046562026e37a29dec8aacf. Verified 2026-09-06.
The area mapping tool treats exposure as a pure gain in both measurement and
correction. Processing applies an offset and a gain depending on that offset,
so the tool can report the wrong brightness and fail to reach its requested target
even when the current black/white range is valid.
Example and source path
For a normalized neutral input profile, sample input 0.25, black 0.10 and a target
luminance of 0.50:
- Correction passes white = 0.25 / 0.50 = 0.50 to the setter
(src/iop/exposure.c:994), yielding +1 EV with compensations off. - Processing instead produces
(0.25 - 0.10) / (0.50 - 0.10) = 0.375
(exposure.c:516-517,:565-571). That is 25% below the requested target. - The actual required white is
0.10 + (0.25 - 0.10) / 0.50 = 0.40, corresponding
to approximately +1.32193 EV. - At +1 EV, measurement also predicts 0.50 because it multiplies input XYZ by
exp2f(exposure)(exposure.c:954-964), while processing still produces 0.375.
Black 0.10 is inside the slider's normal soft range (exposure.c:1324), and black
is below white throughout this example. This is not an inverted/invalid edit.
The default small negative black value makes the discrepancy smaller, not absent.
The correction discrepancy was executed using color_picker_apply() from both
compiled plugins, followed by module parameter commitment and CPU processing:
both returned +1 EV and output 0.375 for the above target. The measurement discrepancy
was established from its formula; the measurement GUI was not executed.
Recommendation and related work
Use the actual affine exposure transform for measurement and solve its inverse for
correction. Account for how the black offset transforms through the input profile,
and handle nonpositive/unreachable targets without invalid parameter writes.
Related: #22184
The present report covers manual mode; it does not duplicate that mode-guard issue.
#22005 has a related affine-inverse error in color-checker normalization reporting,
but uses a different consumer and needs a different fix.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/iop/exposure.c at the measurement code around lines 954-964, the correction setter around line 994, and processing around lines 516-517 and 565-571. Trace color_picker_apply() in both compiled plugins and the black-range handling around line 1324. Done means measurement and correction use the affine exposure transform, solve its inverse safely, and avoid invalid writes for nonpositive or unreachable targets.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- computer-graphics
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 65/100