Skip to content

fix(canvas): color manage Peek Negative, so the orange mask survives - #908

Merged
marcinz606 merged 1 commit into
marcinz606:mainfrom
seanharding:fix/peek-negative-color-management
Aug 19, 2026
Merged

fix(canvas): color manage Peek Negative, so the orange mask survives#908
marcinz606 merged 1 commit into
marcinz606:mainfrom
seanharding:fix/peek-negative-color-management

Conversation

@seanharding

Copy link
Copy Markdown
Contributor

Peek Negative painted the decoded source straight to the canvas as though it were already display RGB, which drained the film base: on a C-41 camera scan the mask read at R/B 1.70 against 2.30 in the file's own embedded preview. Turning Linear RAW on made it worse (1.58), not better — that swaps the camera's white balance for the unbalanced sensor signal, which is green-heavy, and neither decode is the missing piece.

The buffer is in camera primaries, so apply camera_to_working_matrix in _paint_negative_peek and stop marking the frame splash, which had been suppressing the working-to-display conversion as well as the proof. The as-shot multipliers fold into the matrix when the decode skipped them, so the peek is now independent of Linear RAW: measured through the real app, both decodes land on R/B 2.25, against 2.30 for the embedded preview and 2.26 for an offline camera-matrix + working-to-sRGB reference.

The proof stays off, which splash used to cover for. display_transform_params grows a proofed flag for that, carried in metrics as proof and reset alongside splash on every ordinary render, since last_metrics persists between frames.

Sources with no camera matrix (scanner TIFF, JPEG) are already profiled and pass through unchanged.

Peek Negative painted the decoded source straight to the canvas as though it
were already display RGB, which drained the film base: on a C-41 camera scan
the mask read at R/B 1.70 against 2.30 in the file's own embedded preview.
Turning Linear RAW on made it worse (1.58), not better — that swaps the
camera's white balance for the unbalanced sensor signal, which is green-heavy,
and neither decode is the missing piece.

The buffer is in camera primaries, so apply camera_to_working_matrix in
_paint_negative_peek and stop marking the frame splash, which had been
suppressing the working-to-display conversion as well as the proof. The
as-shot multipliers fold into the matrix when the decode skipped them, so the
peek is now independent of Linear RAW: measured through the real app, both
decodes land on R/B 2.25, against 2.30 for the embedded preview and 2.26 for
an offline camera-matrix + working-to-sRGB reference.

The proof stays off, which splash used to cover for. display_transform_params
grows a `proofed` flag for that, carried in metrics as `proof` and reset
alongside `splash` on every ordinary render, since last_metrics persists
between frames.

Sources with no camera matrix (scanner TIFF, JPEG) are already profiled and
pass through unchanged.
@marcinz606
marcinz606 merged commit 1d2fa8c into marcinz606:main Aug 19, 2026
1 check passed
@seanharding
seanharding deleted the fix/peek-negative-color-management branch August 19, 2026 17:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants