A brightness slider can work perfectly as UI while producing the wrong pixels. In Photoshot, my browser image editor, the difficult part was matching a measured brightness/contrast response while keeping the adjustment non-destructive and integrated with masks, opacity and saved projects.
This is a compact account of the reference code, the numerical failure, the correction, and what was actually verified.
1. The first implementation and its reference
The September 18 development record shows Konva's src/filters/Contrast.ts being inspected before the first adjustment engine was written. Its midpoint-centered pixel loop was useful for understanding the channel range and the fact that contrast need not modify alpha.
Photoshot used separately written expressions: brighten toward white or darken toward black, then apply contrast around normalized midpoint 0.5. The original-revision branch remains in the source:
if (t === 'brightness' && a.revision !== 2) {
x = v.brightness < 0 ? x * (1 + v.brightness / 100) : x + ((1 - x) * v.brightness) / 100;
const contrast = v.contrast < 0 ? 1 + v.contrast / 100 : 1 / (1 - v.contrast / 101);
x = (x - 0.5) * contrast + 0.5;
}
The engine already compiled three 256-entry channel lookup tables. The later correction changed their response calculation, not the existence of lookup tables.
2. The measured failure
On September 25, an intermediate normal-mode approximation was compared with Photoshop 27.3.1 at brightness +30 and contrast +20. It produced mean absolute RGB-channel error 11.505 and maximum error 25.
Two retained gray samples make the failure concrete:
| Input | Intermediate output | Archived Photoshop output |
|---|---|---|
| 0 | 25 | 0 |
| 128 | 168 | 157 |
Those errors belong to the intermediate build used in that comparison. They must not be presented as a measurement of the first September 18 legacy formula.
Historical chart measurements at +30/+20; each bar is one deterministic evaluation.
3. Why consulting GitHub was not the entire solution
Konva was a consulted source, not an installed, verbatim replacement for our filter. A public contrast implementation may target a different response curve. It also does not supply our adjustment-layer serialization, mask integration or old-project behavior.
The actual chronology was reference lookup → application implementation → later comparison → calibration. The reference was not first discovered after the September 25 failure.
4. Replace the approximation with sampled responses
Calibration used a synthetic gray ramp in Photoshop normal mode. Brightness was sampled from −150 to +150 and contrast from −50 to +100, in steps of 10, with the other control held at zero. The data are retained in tone-response.ts.
sampleResponse interpolates intermediate settings and channel positions. Revision 2 normal mode applies brightness first, then contrast:
x = sampleResponse(toneResponse.brightness, v.brightness, -150, x);
x = sampleResponse(toneResponse.contrast, v.contrast, -50, x);
The order is meaningful: C(B(x)) generally differs from B(C(x)). The result still flows through the existing floating-point channel tables. Masks and opacity remain compositor responsibilities; old revision behavior and the separate Legacy option remain distinct branches.
5. The result—and a control that reverses the order
The historical chart was 256 × 32 pixels: eight gray-ramp rows followed by mixed RGB rows. Alpha was excluded, leaving 24,576 channel samples.
| Historical implementation, +30/+20 | Mean absolute error | Maximum |
|---|---|---|
| Intermediate approximation | 11.505 | 25 |
| Measured response, brightness → contrast | 0.241211 | 1 |
| Measured response, contrast → brightness | 1.149740 | 4 |
For that chart condition, the mean error fell by approximately 97.9% relative to the intermediate approximation. That is an error reduction, not a universal compatibility or visual-quality score. Each row is one deterministic chart evaluation, so there is no invented confidence interval or speed claim.
Numeric records visualized as patches and curves; historical measurements and the new replay remain distinct.
6. What the current rerun verifies
The unchanged public engine's response tables were compared with the archived calibration JSON and match exactly. A fresh source-level replay then evaluated nine retained gray inputs at each of +30/+20, +17/+13 and −65/−23: 27/27 outputs equal the archived Photoshot outputs.
That does not mean 27/27 equal Photoshop exactly; some retained Photoshop comparisons differ by one channel value. Nor does this rerun recompute the full-chart means: the original reference PNGs were unavailable in the reviewed folder. Historical chart statistics, archived Photoshop samples and the new replay are deliberately separated.
Sources and full figures
- Konva Contrast.ts: consulted reference
- Photoshot adjustment engine at 19f45ed
- Measured response data and interpolation
For the full version, including the pipeline diagram, before/after error charts, gray-value comparisons and reproducibility files, read the complete research note on my website.
Writing and source review were assisted by AI. Claims above are tied to the cited source and retained measurement records.


Top comments (0)