Skip to main content

display_types/
transfer.rs

1#[cfg(any(feature = "alloc", feature = "std"))]
2use crate::prelude::Vec;
3
4/// Bit-depth encoding for transfer characteristic sample points, decoded from
5/// the Transfer Characteristics Block (DisplayID 1.x `0x0E`) byte 0 bits 7:6.
6///
7/// The same three encodings are used by the CEA-861 VESA Display Transfer
8/// Characteristic Data Block (standard tag `0x05`).
9#[non_exhaustive]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum TransferPointEncoding {
13    /// 8 bits per luminance point: one byte per sample, range 0–255.
14    Bits8,
15    /// 10 bits per luminance point: 5 bytes packed MSB-first per 4 samples, range 0–1023.
16    Bits10,
17    /// 12 bits per luminance point: 3 bytes packed MSB-first per 2 samples, range 0–4095.
18    Bits12,
19}
20
21/// Transfer curve sample data decoded from the DisplayID Transfer Characteristics
22/// Block (`0x0E`).
23///
24/// Sample values are normalized to `[0.0, 1.0]` and represent evenly-spaced input
25/// levels from black (`0`) to white (`1`).
26#[non_exhaustive]
27#[cfg(any(feature = "alloc", feature = "std"))]
28#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
29#[derive(Debug, Clone, PartialEq)]
30pub enum TransferCurve {
31    /// Single luminance transfer curve (grayscale / single-channel mode).
32    Luminance(Vec<f32>),
33    /// Separate per-primary transfer curves (multi-channel mode, byte 0 bit 5 set).
34    Rgb {
35        /// Red primary transfer curve.
36        red: Vec<f32>,
37        /// Green primary transfer curve.
38        green: Vec<f32>,
39        /// Blue primary transfer curve.
40        blue: Vec<f32>,
41    },
42}
43
44/// Decoded Transfer Characteristics Block (DisplayID 1.x `0x0E`).
45///
46/// Encodes the display's native luminance transfer function as a sequence of sample
47/// points at evenly-spaced input levels from 0 (black) to 1 (white). Stored in
48/// [`crate::DisplayCapabilities::transfer_characteristic`].
49#[non_exhaustive]
50#[cfg(any(feature = "alloc", feature = "std"))]
51#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
52#[derive(Debug, Clone, PartialEq)]
53pub struct DisplayIdTransferCharacteristic {
54    /// Bit depth used to pack each sample value.
55    pub encoding: TransferPointEncoding,
56    /// Sample data — either a single luminance curve or separate R, G, B curves.
57    pub curve: TransferCurve,
58}
59
60#[cfg(any(feature = "alloc", feature = "std"))]
61impl DisplayIdTransferCharacteristic {
62    /// Constructs a [`DisplayIdTransferCharacteristic`] from its decoded fields.
63    pub fn new(encoding: TransferPointEncoding, curve: TransferCurve) -> Self {
64        Self { encoding, curve }
65    }
66}