mediaframe/source/rgbf16/mod.rs
1//! Packed **RGBF16** source (FFmpeg `AV_PIX_FMT_RGBF16`) — 16-bit
2//! half-precision float per channel, byte order `R, G, B` per pixel
3//! (6 bytes / 3 × `half::f16` per pixel).
4//!
5//! Like the Tier 6 8-bit packed-RGB family ([`super::Rgb24`] etc.),
6//! the input is already RGB — there is no chroma matrix work. Outputs
7//! map to the sink's standard channels (with a saturating cast back
8//! to integer for u8 / u16 / luma / HSV outputs):
9//! - `with_rgb` — clamp `[0, 1]` × 255 → packed `R, G, B` u8.
10//! - `with_rgba` — same RGB conversion + constant `0xFF` alpha.
11//! - `with_rgb_u16` — clamp `[0, 1]` × 65535 → packed `R, G, B` u16.
12//! - `with_rgba_u16` — same RGB conversion + constant `0xFFFF` alpha.
13//! - `with_luma` / `with_luma_u16` — derives Y' from R/G/B (after the
14//! clamp + cast to u8) using the existing `rgb_to_luma_row` /
15//! `rgb_to_luma_u16_row` kernels.
16//! - `with_hsv` — clamp + cast to u8 staging followed by the existing
17//! `rgb_to_hsv_row` kernel.
18//! - `with_rgb_f16` — **lossless** half-float pass-through: the source
19//! row is copied verbatim into the output buffer (HDR values > 1.0
20//! are preserved).
21//! - `with_rgb_f32` — lossless widening: each `f16` element is widened
22//! to `f32` (HDR values > 1.0 are preserved).
23//!
24//! HDR values > 1.0 in the source saturate to the output range for
25//! every integer output. No tone mapping is applied.
26//!
27//! Downstream conversion widens `f16` → `f32` at row entry, then
28//! reuses the existing `rgbf32_to_*_row` kernels (Tier 9 completion).
29
30use crate::frame::Rgbf16Frame;
31
32walker! {
33 packed_be {
34 /// Zero-sized marker for the packed **RGBF16** source format.
35 /// `<const BE: bool = false>` mirrors the parent
36 /// [`Rgbf16Frame`](crate::frame::Rgbf16Frame)'s endian flag — `false` (default) selects
37 /// `AV_PIX_FMT_RGBF16LE`, `true` selects `AV_PIX_FMT_RGBF16BE`.
38 #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
39 marker: Rgbf16,
40 frame: Rgbf16Frame,
41 row: Rgbf16Row,
42 sink: Rgbf16Sink,
43 walker: rgbf16_to,
44 walker_endian: rgbf16_to_endian,
45 buf_field: rgb,
46 elem_type: half::f16,
47 row_elems: |w| w * 3,
48 row_doc: "One row of an [`Rgbf16`] source — `width * 3` packed\n\
49 `half::f16` samples (`R, G, B` per pixel). The Row type\n\
50 is **not** parameterized on `BE` — it just borrows the\n\
51 underlying byte slice; the kernel's BE-aware byte-swap\n\
52 is monomorphized via the parent `Rgbf16<BE>` marker.",
53 walker_doc: "Walks an [`Rgbf16Frame`](crate::frame::Rgbf16Frame) row by row into the sink.\n\
54 The `<const BE>` parameter is propagated from the\n\
55 frame to the sink-trait bound (`S: Rgbf16Sink<BE>`)\n\
56 so the row-kernel call inside `process` monomorphizes\n\
57 against the same byte order.",
58 }
59}
60
61#[cfg(all(test, feature = "std"))]
62mod tests;