use crate::modespec::ModeSpec;
#[allow(clippy::too_many_arguments, clippy::cast_possible_truncation)]
pub(crate) fn decode_line(
spec: ModeSpec,
line_index: u32,
audio: &[f32],
skip_samples: i64,
line_seconds_offset: f64,
rate_hz: f64,
image: &mut crate::image::SstvImage,
demod: &mut crate::mode_pd::PdDemod,
snr_est: &mut crate::snr::SnrEstimator,
hedr_shift_hz: f64,
) {
let pixel_secs = spec.pixel_seconds;
let sync_secs = spec.sync_seconds;
let porch_secs = spec.porch_seconds;
let septr_secs = spec.septr_seconds;
let width = spec.line_pixels;
let chan_len = f64::from(width) * pixel_secs;
let chan_starts_sec: [f64; 3] = [
septr_secs, 2.0 * septr_secs + chan_len, 2.0 * septr_secs + 2.0 * chan_len + sync_secs + porch_secs, ];
let width_us = width as usize;
let chan_bounds_abs: [(i64, i64); 3] = std::array::from_fn(|i| {
let start_sec = chan_starts_sec[i];
let end_sec = start_sec + chan_len;
let start_abs = skip_samples + ((line_seconds_offset + start_sec) * rate_hz).round() as i64;
let end_abs = skip_samples + ((line_seconds_offset + end_sec) * rate_hz).round() as i64;
(start_abs, end_abs)
});
let mut g = vec![0_u8; width_us];
let mut b = vec![0_u8; width_us];
let mut r = vec![0_u8; width_us];
let buffers: [&mut [u8]; 3] = [&mut g, &mut b, &mut r];
for (chan_idx, buf) in buffers.into_iter().enumerate() {
crate::mode_pd::decode_one_channel_into(
buf,
chan_starts_sec[chan_idx],
chan_bounds_abs[chan_idx],
spec,
audio,
skip_samples,
line_seconds_offset,
rate_hz,
demod,
snr_est,
hedr_shift_hz,
);
}
for x in 0..width_us {
image.put_pixel(x as u32, line_index, [r[x], g[x], b[x]]);
}
}