X-Git-Url: https://git.nihav.org/?p=nihav.git;a=blobdiff_plain;f=nihav-core%2Fsrc%2Fscale%2Frepack.rs;h=8cdb8ea91b164df63ecb22409fd196bdef12b4cf;hp=fd59e78046b355d7e735cfb38c06a595128027b6;hb=25e0bf9a974b1bb5a8f8b38e23b4a7e91db3eab0;hpb=e243ceb4d694cc08767ad70027bb6963f4cefea3 diff --git a/nihav-core/src/scale/repack.rs b/nihav-core/src/scale/repack.rs index fd59e78..8cdb8ea 100644 --- a/nihav-core/src/scale/repack.rs +++ b/nihav-core/src/scale/repack.rs @@ -33,8 +33,8 @@ impl PackKernel { } impl Kernel for PackKernel { - fn init(&mut self, in_fmt: &ScaleInfo, dest_fmt: &ScaleInfo) -> ScaleResult { - self.ncomps = in_fmt.fmt.components as usize; + fn init(&mut self, in_fmt: &ScaleInfo, dest_fmt: &ScaleInfo, _options: &[(String, String)]) -> ScaleResult { + self.ncomps = in_fmt.fmt.components.min(dest_fmt.fmt.components) as usize; for i in 0..self.ncomps { let ichr = in_fmt.fmt.comp_info[i].unwrap(); let ochr = dest_fmt.fmt.comp_info[i].unwrap(); @@ -120,8 +120,17 @@ impl UnpackKernel { } impl Kernel for UnpackKernel { - fn init(&mut self, in_fmt: &ScaleInfo, dest_fmt: &ScaleInfo) -> ScaleResult { - self.ncomps = in_fmt.fmt.components as usize; + fn init(&mut self, in_fmt: &ScaleInfo, dest_fmt: &ScaleInfo, options: &[(String, String)]) -> ScaleResult { + let mut debug = false; + for (name, value) in options.iter() { + match (name.as_str(), value.as_str()) { + ("debug", "") => { debug = true; }, + ("debug", "true") => { debug = true; }, + _ => {}, + } + } + + self.ncomps = in_fmt.fmt.components.min(dest_fmt.fmt.components) as usize; let mut chr: Vec> = Vec::with_capacity(MAX_CHROMATONS); for i in 0..self.ncomps { let ichr = in_fmt.fmt.comp_info[i].unwrap(); @@ -143,17 +152,19 @@ impl Kernel for UnpackKernel { chr.push(Some(dchr)); } let mut df = in_fmt.fmt; - for i in 0..self.ncomps { - df.comp_info[i] = chr[i]; + df.comp_info[..self.ncomps].clone_from_slice(&chr[..self.ncomps]); + df.components = self.ncomps as u8; + df.palette = false; + if debug { + println!(" [intermediate format {}]", df); } -println!(" [intermediate format {}]", df); let res = alloc_video_buffer(NAVideoInfo::new(in_fmt.width, in_fmt.height, false, df), 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) = pic_in.get_vbuf() { - let step = buf.get_info().get_format().get_chromaton(0).unwrap().get_step() as usize; + let step = buf.get_info().get_format().elem_size as usize; let mut soff: [usize; MAX_CHROMATONS] = [0; MAX_CHROMATONS]; for i in 0..self.ncomps { soff[i] = buf.get_info().get_format().get_chromaton(i).unwrap().get_offset() as usize; @@ -163,6 +174,7 @@ println!(" [intermediate format {}]", df); let istride = buf.get_stride(0); let sdata1 = buf.get_data(); let sdata = &sdata1[ioff..]; + let ychr = buf.get_info().get_format().get_chromaton(0).unwrap(); if let Some(ref mut dbuf) = pic_out.get_vbuf() { let mut ostride: [usize; MAX_CHROMATONS] = [0; MAX_CHROMATONS]; let mut offs: [usize; MAX_CHROMATONS] = [0; MAX_CHROMATONS]; @@ -171,13 +183,35 @@ println!(" [intermediate format {}]", df); offs[i] = dbuf.get_offset(i); } let dst = dbuf.get_data_mut().unwrap(); - for src in sdata.chunks(istride).take(h) { - for x in 0..w { - for i in 0..self.ncomps { - dst[offs[i] + x] = src[x * step + soff[i]]; + if ychr.next_elem == 0 || usize::from(ychr.next_elem) == step { + for src in sdata.chunks(istride).take(h) { + for x in 0..w { + for i in 0..self.ncomps { + dst[offs[i] + x] = src[x * step + soff[i]]; + } } + for i in 0..self.ncomps { offs[i] += ostride[i]; } + } + } else { + let mut steps: [usize; MAX_CHROMATONS] = [0; MAX_CHROMATONS]; + for i in 0..self.ncomps { + steps[i] = buf.get_info().get_format().get_chromaton(i).unwrap().next_elem as usize; + } + + for src in sdata.chunks(istride).take(h) { + let mut x = offs; + for piece in src.chunks(step) { + for i in 0..self.ncomps { + let mut co = soff[i]; + while co < step { + dst[x[i]] = piece[co]; + x[i] += 1; + co += steps[i]; + } + } + } + for i in 0..self.ncomps { offs[i] += ostride[i]; } } - for i in 0..self.ncomps { offs[i] += ostride[i]; } } } else { unimplemented!(); @@ -233,7 +267,16 @@ impl DepalKernel { } impl Kernel for DepalKernel { - fn init(&mut self, in_fmt: &ScaleInfo, _dest_fmt: &ScaleInfo) -> ScaleResult { + fn init(&mut self, in_fmt: &ScaleInfo, _dest_fmt: &ScaleInfo, options: &[(String, String)]) -> ScaleResult { + let mut debug = false; + for (name, value) in options.iter() { + match (name.as_str(), value.as_str()) { + ("debug", "") => { debug = true; }, + ("debug", "true") => { debug = true; }, + _ => {}, + } + } + //todo select output more fitting for dest_fmt if possible self.ncomps = in_fmt.fmt.components as usize; let mut chr: Vec> = Vec::with_capacity(MAX_CHROMATONS); @@ -252,10 +295,10 @@ impl Kernel for DepalKernel { } let mut df = in_fmt.fmt; df.palette = false; - for i in 0..self.ncomps { - df.comp_info[i] = chr[i]; + df.comp_info[..self.ncomps].clone_from_slice(&chr[..self.ncomps]); + if debug { + println!(" [intermediate format {}]", df); } -println!(" [intermediate format {}]", df); let res = alloc_video_buffer(NAVideoInfo::new(in_fmt.width, in_fmt.height, false, df), 3); if res.is_err() { return Err(ScaleError::AllocError); } Ok(res.unwrap())