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}