Add the B&W HIGH CONTRAST film sim next to ACRIPES

A second black-and-white stock, so it gets its own baseFilter rather than
borrowing Acros': the PHOTO STYLE chips are keyed by baseFilter and the two
greys have to sit side by side.

The look is the B&W MIX plus a push at both ends. The mix rides the matrix — a
non-BT.709 row set (0.38/0.56/0.06, identical rows, sum 1.00) so a red roof
reads bright, a blue sky deep, and the separation is contrast before any curve.
The push rides FILM_TONE (shadow -0.32, highlight +0.26) so the ends move
without touching the midtones, and the midtone slope is SIM_CONTRAST_BIAS (4
contrast units). Every knob still opens at neutral: a sim is colour and tone
only.

Both B&W stocks being mono is now asked once, through isMonochromeBase, so the
colour-only stages (saturation, white balance, the R/B fine-tune) and the
chrome/hue-mixer gate can never half-apply to one of them.

Mirrors the web app's rail (c403dd0).
This commit is contained in:
2026-09-22 19:25:54 +07:00
parent c403dd04c8
commit 3d273a3188
4 changed files with 67 additions and 6 deletions
+5 -1
View File
@@ -62,7 +62,11 @@ export const MIN_CROP_FRAC = 0.08;
// cool tint in shade, plus a seasonal atmospheric haze/fog veil.
export type CinemaSeason = 'spring' | 'summer' | 'autumn' | 'winter';
export type BaseFilter = 'classic-neg' | 'classic-chrome' | 'provia' | 'velvia' | 'astia' | 'eterna' | 'monochrome' | 'leica' | 'leica-vivid' | 'none';
// `monochrome` is Acros' grey ramp; `mono-high-contrast` is the B&W HIGH
// CONTRAST stock's own — both are black-and-white, so anything that asks "is
// this a colour stock?" must ask it through isMonochromeBase (colorUtils.ts)
// rather than comparing against one of these two strings.
export type BaseFilter = 'classic-neg' | 'classic-chrome' | 'provia' | 'velvia' | 'astia' | 'eterna' | 'monochrome' | 'mono-high-contrast' | 'leica' | 'leica-vivid' | 'none';
export interface ColorAdjustments {
exposure: number; // -10 to +10 (mapped to matrix multiplier or offset)