From: Kostya Shishkov Date: Sat, 7 Mar 2026 19:44:35 +0000 (+0100) Subject: nihav_core/scale: add a stage for high- to 8-bit image conversion X-Git-Url: https://git.nihav.org/?a=commitdiff_plain;h=29ae6c5c1528e75b59b1256503ed8b514b7615c8;p=nihav.git nihav_core/scale: add a stage for high- to 8-bit image conversion --- diff --git a/nihav-core/src/scale/depth.rs b/nihav-core/src/scale/depth.rs new file mode 100644 index 0000000..a44e324 --- /dev/null +++ b/nihav-core/src/scale/depth.rs @@ -0,0 +1,53 @@ +use super::*; +use super::kernel::Kernel; + +#[derive(Default)] +struct ShallowKernel { +} + +impl ShallowKernel { + fn new() -> Self { Self::default() } +} + +impl Kernel for ShallowKernel { + fn init(&mut self, in_fmt: &ScaleInfo, dest_fmt: &ScaleInfo, _options: &[(String, String)]) -> ScaleResult { + let mut wrk_fmt = in_fmt.fmt; + for (comp, tcomp) in wrk_fmt.comp_info.iter_mut().zip(dest_fmt.fmt.comp_info.iter()) { + if let (Some(ref mut wcomp), Some(ref tgtcomp)) = (comp, tcomp) { + wcomp.depth = tgtcomp.depth; + } + } + let res = alloc_video_buffer(NAVideoInfo::new(in_fmt.width, in_fmt.height, false, wrk_fmt), 3); + if res.is_err() { return Err(ScaleError::AllocError); } + Ok(res.unwrap()) + } + fn process(&mut self, pic_in: &NABufferType, pic_out: &mut NABufferType) { + if let (Some(ref buf), Some(ref mut dbuf)) = (pic_in.get_vbuf16(), pic_out.get_vbuf()) { + let ncomps = buf.get_info().get_format().get_num_comp(); + for comp in 0..ncomps { + let ioff = buf.get_offset(comp); + let istride = buf.get_stride(comp); + let idepth = buf.get_info().get_format().get_chromaton(comp).unwrap().get_depth(); + let ddepth = dbuf.get_info().get_format().get_chromaton(comp).unwrap().get_depth(); + let dshift = idepth - ddepth; + let (w, h) = dbuf.get_dimensions(comp); + let sdata = buf.get_data(); + let sdata = &sdata[ioff..]; + let doff = dbuf.get_offset(comp); + let dstride = dbuf.get_stride(comp); + let ddata = dbuf.get_data_mut().unwrap(); + for (sline, dline) in sdata.chunks(istride).zip(ddata[doff..].chunks_mut(dstride)).take(h) { + for (&src, dst) in sline.iter().zip(dline.iter_mut()).take(w) { + *dst = (src >> dshift) as u8; + } + } + } + } else { + unimplemented!("shallower not on 16->8"); + } + } +} + +pub fn create_shallow() -> Box { + Box::new(ShallowKernel::new()) +} diff --git a/nihav-core/src/scale/mod.rs b/nihav-core/src/scale/mod.rs index 85f7b83..4ccdb9e 100644 --- a/nihav-core/src/scale/mod.rs +++ b/nihav-core/src/scale/mod.rs @@ -20,6 +20,7 @@ use crate::frame::*; mod kernel; mod colorcvt; +mod depth; mod fill; mod repack; #[allow(clippy::module_inception)] @@ -92,6 +93,7 @@ const KERNELS: &[KernelDesc] = &[ KernelDesc { name: "depal", create: repack::create_depal }, KernelDesc { name: "palette", create: palette::create_palettise }, KernelDesc { name: "scale", create: scale::create_scale }, + KernelDesc { name: "shallow", create: depth::create_shallow }, KernelDesc { name: "fill", create: fill::create_fill }, KernelDesc { name: "rgb_to_yuv", create: colorcvt::create_rgb2yuv }, KernelDesc { name: "yuv_to_rgb", create: colorcvt::create_yuv2rgb }, @@ -362,6 +364,16 @@ fn build_pipeline(ifmt: &ScaleInfo, ofmt: &ScaleInfo, just_convert: bool, option cur_fmt = new_stage.fmt_out; add_stage!(stages, new_stage); } + let is_in_high_bd = cur_fmt.fmt.get_max_depth() > 8; + let is_out_high_bd = ofmt.fmt.get_max_depth() > 8; + if is_in_high_bd && !is_out_high_bd { + if debug { + println!("[adding shallow]"); + } + let new_stage = Stage::new("shallow", &cur_fmt, ofmt, options)?; + cur_fmt = new_stage.fmt_out; + add_stage!(stages, new_stage); + } let icomponents = cur_fmt.fmt.components - if cur_fmt.fmt.alpha { 1 } else { 0 }; let ocomponents = ofmt.fmt.components - if ofmt.fmt.alpha { 1 } else { 0 }; if !needs_palettise && ((!cur_fmt.fmt.alpha && ofmt.fmt.alpha) || (icomponents < ocomponents)) {