#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
enum SbMode {
#[default]
Off,
Capture,
Replay,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
enum TxSel {
#[default]
Dct,
Adst,
AdstDct,
DctAdst,
Idtx,
SplitDct,
}
impl TxSel {
fn from_flags(adst: bool, idtx: bool, adstdct: bool, dctadst: bool) -> Self {
if idtx {
TxSel::Idtx
} else if adst {
TxSel::Adst
} else if adstdct {
TxSel::AdstDct
} else if dctadst {
TxSel::DctAdst
} else {
TxSel::Dct
}
}
}
const NO_FILTER: u8 = 0xff;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
struct LumaSel {
mode: u8,
delta: i8,
palette: u8,
filter: u8,
tx: TxSel,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
struct UvSel {
uv: u8,
}
#[derive(Default, Clone, PartialEq)]
struct DecisionRecord {
parts: Vec<Part16>,
luma: Vec<LumaSel>,
uv: Vec<UvSel>,
luma_cf: Vec<Vec<i32>>,
uv_cf: Vec<[Vec<i32>; 2]>,
cfl: Vec<[i32; 2]>,
recon: Vec<[Vec<i32>; 3]>,
}
#[derive(Default, Clone, Copy)]
struct RecordCursor {
parts: usize,
luma: usize,
uv: usize,
}
impl<'a> LossyTile<'a> {
#[inline]
fn part_decision(&mut self, f: impl Fn(&Self) -> Part16) -> Part16 {
match self.sb_mode {
SbMode::Off => f(self),
SbMode::Capture => {
let c = f(self);
self.rec.parts.push(c);
c
}
SbMode::Replay => {
let c = self.rec.parts[self.cur.parts];
self.cur.parts += 1;
c
}
}
}
#[inline]
fn luma_sel_replay(&mut self) -> Option<LumaSel> {
if self.sb_mode == SbMode::Replay {
let s = self.rec.luma[self.cur.luma];
self.cur.luma += 1;
Some(s)
} else {
None
}
}
#[inline]
fn push_luma_sel(&mut self, s: LumaSel) {
if self.sb_mode == SbMode::Capture {
self.rec.luma.push(s);
}
}
#[inline]
fn uv_sel_replay(&mut self) -> Option<UvSel> {
if self.sb_mode == SbMode::Replay {
let s = self.rec.uv[self.cur.uv];
self.cur.uv += 1;
Some(s)
} else {
None
}
}
#[inline]
fn luma_cf_replay(&mut self) -> Option<Vec<i32>> {
if self.sb_mode == SbMode::Replay {
Some(std::mem::take(&mut self.rec.luma_cf[self.cur.luma - 1]))
} else {
None
}
}
#[inline]
fn push_luma_cf(&mut self, cf: &[i32]) {
if self.sb_mode == SbMode::Capture {
self.rec.luma_cf.push(cf.to_vec());
}
}
#[inline]
fn uv_cf_replay(&mut self) -> Option<([Vec<i32>; 2], [i32; 2])> {
if self.sb_mode == SbMode::Replay {
let i = self.cur.uv - 1;
Some((std::mem::take(&mut self.rec.uv_cf[i]), self.rec.cfl[i]))
} else {
None
}
}
#[inline]
fn push_uv_cf(&mut self, u: &[i32], v: &[i32], cfl: [i32; 2]) {
if self.sb_mode == SbMode::Capture {
self.rec.uv_cf.push([u.to_vec(), v.to_vec()]);
self.rec.cfl.push(cfl);
}
}
#[inline]
fn push_uv_sel(&mut self, s: UvSel) {
if self.sb_mode == SbMode::Capture {
self.rec.uv.push(s);
}
}
}