Skip to main content

ff_filter/
blend.rs

1//! Blend mode definitions for video compositing operations.
2
3// ── BlendMode ────────────────────────────────────────────────────────────────
4
5/// Specifies how two video layers are combined during compositing.
6///
7/// Variants are grouped into two families:
8///
9/// - **Photographic blend modes** (18) — operate on pixel values; both layers
10///   are typically opaque.  Implemented via `FFmpeg`'s `blend` filter with the
11///   `all_mode` option, except [`BlendMode::Normal`] which uses `overlay`.
12///
13/// - **Porter-Duff alpha compositing** (6) — operate on the alpha channel;
14///   at least the top layer must carry an alpha channel (e.g. `rgba` or
15///   `yuva420p` pixel format).
16///
17/// # Implementation status
18///
19/// All 14 arithmetic photographic modes and all 6 Porter-Duff operations are
20/// fully implemented and covered by regression tests (issues #327–#347).
21///
22/// The four HSL-space modes — [`BlendMode::Hue`], [`BlendMode::Saturation`],
23/// [`BlendMode::Color`], and [`BlendMode::Luminosity`] — are accepted by the
24/// builder but produce no output at runtime: `FFmpeg`'s `blend` filter does not
25/// include these mode names in the bundled version.  The builder returns
26/// [`FilterError::BuildFailed`](crate::FilterError) when the filter graph
27/// cannot be configured for these modes.
28#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29pub enum BlendMode {
30    // ── Photographic blend modes ──────────────────────────────────────────
31    /// Standard alpha-over composite (top * opacity + bottom * (1 − opacity)).
32    ///
33    /// Implemented via `FFmpeg`'s `overlay=format=auto:shortest=1`.
34    Normal,
35
36    /// Multiply per-channel pixel values; darkens the result.
37    ///
38    /// Maps to `blend all_mode=multiply`.
39    Multiply,
40
41    /// Inverse of multiply; lightens the result.
42    ///
43    /// Maps to `blend all_mode=screen`.
44    Screen,
45
46    /// Combines Multiply and Screen based on base-layer luminance.
47    ///
48    /// Maps to `blend all_mode=overlay`.
49    Overlay,
50
51    /// Gentle contrast enhancement; 50 % gray top layer is identity.
52    ///
53    /// Maps to `blend all_mode=softlight`.
54    SoftLight,
55
56    /// Harsher version of Overlay; driven by the top layer's luminance.
57    ///
58    /// Maps to `blend all_mode=hardlight`.
59    HardLight,
60
61    /// Brightens the base by dividing it by the inverse of the blend.
62    ///
63    /// Maps to `blend all_mode=dodge`.
64    ColorDodge,
65
66    /// Darkens the base; inverse of Color Dodge.
67    ///
68    /// Maps to `blend all_mode=burn`.
69    ColorBurn,
70
71    /// Retains the darker of the two pixels per channel.
72    ///
73    /// Maps to `blend all_mode=darken`.
74    Darken,
75
76    /// Retains the lighter of the two pixels per channel.
77    ///
78    /// Maps to `blend all_mode=lighten`.
79    Lighten,
80
81    /// Per-channel absolute difference.  Useful for alignment verification.
82    ///
83    /// Maps to `blend all_mode=difference`.
84    Difference,
85
86    /// Similar to Difference but with lower contrast in mid-tones.
87    ///
88    /// Maps to `blend all_mode=exclusion`.
89    Exclusion,
90
91    /// Linear addition, clamped at maximum.
92    ///
93    /// Maps to `blend all_mode=addition`.
94    Add,
95
96    /// Linear subtraction, clamped at minimum.
97    ///
98    /// Maps to `blend all_mode=subtract`.
99    Subtract,
100
101    /// Applies the top layer's hue to the base's saturation and luminance.
102    ///
103    /// Maps to `blend all_mode=hue`.
104    ///
105    /// **Note**: not supported by the bundled `FFmpeg` `blend` filter; graph
106    /// construction succeeds but no output frame is produced at runtime.
107    Hue,
108
109    /// Applies the top layer's saturation to the base's hue and luminance.
110    ///
111    /// Maps to `blend all_mode=saturation`.
112    ///
113    /// **Note**: not supported by the bundled `FFmpeg` `blend` filter; graph
114    /// construction succeeds but no output frame is produced at runtime.
115    Saturation,
116
117    /// Applies the top layer's hue + saturation to the base's luminance.
118    ///
119    /// Maps to `blend all_mode=color`.
120    ///
121    /// **Note**: not supported by the bundled `FFmpeg` `blend` filter; graph
122    /// construction succeeds but no output frame is produced at runtime.
123    Color,
124
125    /// Applies the top layer's luminance to the base's hue and saturation.
126    ///
127    /// Maps to `blend all_mode=luminosity`.
128    ///
129    /// **Note**: not supported by the bundled `FFmpeg` `blend` filter; graph
130    /// construction succeeds but no output frame is produced at runtime.
131    Luminosity,
132
133    // ── Porter-Duff alpha compositing ─────────────────────────────────────
134    /// Top layer rendered over the bottom (standard alpha compositing).
135    ///
136    /// Implemented via `overlay=format=auto:shortest=1`.
137    PorterDuffOver,
138
139    /// Bottom layer rendered over the top; equivalent to `Over` with inputs swapped.
140    PorterDuffUnder,
141
142    /// Top layer masked by the bottom layer's alpha (intersection).
143    PorterDuffIn,
144
145    /// Top layer visible only where the bottom layer is transparent.
146    PorterDuffOut,
147
148    /// Top layer placed atop the bottom; visible only where the bottom is opaque.
149    PorterDuffAtop,
150
151    /// Pixels from exactly one layer (XOR of opaque regions).
152    PorterDuffXor,
153}