use bitvec::{field::BitField, view::BitView};
use crate::prelude::internal::*;
#[tracing::instrument(skip_all)]
pub(crate) fn parse(input: &[u8]) -> StandardTimings {
StandardTimings {
st1: one(&input[0x26..=0x27]),
st2: one(&input[0x28..=0x29]),
st3: one(&input[0x2a..=0x2b]),
st4: one(&input[0x2c..=0x2d]),
st5: one(&input[0x2e..=0x2f]),
st6: one(&input[0x30..=0x31]),
st7: one(&input[0x32..=0x33]),
st8: one(&input[0x34..=0x35]),
}
}
#[tracing::instrument]
pub(crate) fn one(bytes: &[u8]) -> Option<STiming> {
if bytes[0] == 0x01 && bytes[1] == 0x01 {
return None;
}
if bytes[0] == 0x01 && bytes[1] == 0x00 {
tracing::warn!(
"Standard timing used an [0x01, 0x00] to show that the timing \
was unused. This is against the standard. \
Consider using [0x01, 0x01] instead."
);
return None;
}
let horizontal_addr_pixel_ct = hoz_addr_pixels(bytes[0])?;
let bits: &bitvec::prelude::BitSlice<u8> = bytes[1].view_bits();
tracing::debug!("aspect ratio: {:#?}", (bits[7], bits[6]));
let aspect_ratio = match (bits[7], bits[6]) {
(false, false) => StandardAspectRatio::_16_10,
(false, true) => StandardAspectRatio::_4_3,
(true, false) => StandardAspectRatio::_5_4,
(true, true) => StandardAspectRatio::_16_9,
};
let field_refresh_rate = bits[0..=5].load_be::<u8>() + 60;
Some(STiming {
horizontal_addr_pixel_ct,
aspect_ratio,
field_refresh_rate,
})
}
#[tracing::instrument]
fn hoz_addr_pixels(ct: u8) -> Option<u16> {
if ct == 0x00 {
tracing::warn!(
"Standard timing used 0x00 pixel count, which isn't permitted. Returning None."
);
return None;
}
Some((ct as u16 + 31) * 8)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn _2c47316eff13_std_timings() {
logger();
let path = "linuxhw_edid_EDID_Digital_Samsung_SAM02E3_2C47316EFF13.input";
let input = crate::prelude::internal::edid_by_filename(path);
let got = super::parse(&input);
tracing::info!("got: {got:#?}");
let expected = StandardTimings {
st1: Some(STiming {
horizontal_addr_pixel_ct: 1440,
aspect_ratio: StandardAspectRatio::_16_10,
field_refresh_rate: 60,
}),
st2: Some(STiming {
horizontal_addr_pixel_ct: 1440,
aspect_ratio: StandardAspectRatio::_16_10,
field_refresh_rate: 75,
}),
st3: Some(STiming {
horizontal_addr_pixel_ct: 1280,
aspect_ratio: StandardAspectRatio::_5_4,
field_refresh_rate: 60,
}),
st4: Some(STiming {
horizontal_addr_pixel_ct: 1280,
aspect_ratio: StandardAspectRatio::_4_3,
field_refresh_rate: 60,
}),
st5: Some(STiming {
horizontal_addr_pixel_ct: 1152,
aspect_ratio: StandardAspectRatio::_4_3,
field_refresh_rate: 75,
}),
st6: None,
st7: None,
st8: None,
};
tracing::warn!("expected: {expected:#?}");
assert_eq!(got, expected);
}
}