X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-core%2Fsrc%2Fscale%2Fmod.rs;h=4fbf3e696c42f4140be848999824d7daf4e42037;hb=e6aaad5c5273cd814b5748b7faf3751835a37217;hp=6bf6e272273887dac36bad6147bd0147e34b88bc;hpb=25e0bf9a974b1bb5a8f8b38e23b4a7e91db3eab0;p=nihav.git diff --git a/nihav-core/src/scale/mod.rs b/nihav-core/src/scale/mod.rs index 6bf6e27..4fbf3e6 100644 --- a/nihav-core/src/scale/mod.rs +++ b/nihav-core/src/scale/mod.rs @@ -187,7 +187,7 @@ fn copy(pic_in: &NABufferType, pic_out: &mut NABufferType) let dst = &mut ddata[doff..]; let copy_size = sstride.min(dstride); for (dline, sline) in dst.chunks_exact_mut(dstride).take(h).zip(src.chunks_exact(sstride)) { - (&mut dline[..copy_size]).copy_from_slice(&sline[..copy_size]); + dline[..copy_size].copy_from_slice(&sline[..copy_size]); } } } @@ -220,7 +220,7 @@ fn copy(pic_in: &NABufferType, pic_out: &mut NABufferType) let dst = &mut ddata[doff..]; let copy_size = sstride.min(dstride); for (dline, sline) in dst.chunks_exact_mut(dstride).take(h).zip(src.chunks_exact(sstride)) { - (&mut dline[..copy_size]).copy_from_slice(&sline[..copy_size]); + dline[..copy_size].copy_from_slice(&sline[..copy_size]); } } } @@ -263,7 +263,7 @@ fn fmt_needs_scale(ifmt: &NAPixelFormaton, ofmt: &NAPixelFormaton) -> bool { fn build_pipeline(ifmt: &ScaleInfo, ofmt: &ScaleInfo, just_convert: bool, options: &[(String, String)]) -> ScaleResult> { let mut debug = false; for (name, value) in options.iter() { - if name == "debug" && (value == "" || value == "true") { + if name == "debug" && (value.is_empty() || value == "true") { debug = true; break; } @@ -283,7 +283,7 @@ fn build_pipeline(ifmt: &ScaleInfo, ofmt: &ScaleInfo, just_convert: bool, option let needs_unpack = !ifmt.fmt.is_unpacked(); let needs_pack = !ofmt.fmt.is_unpacked(); let needs_convert = inname != outname; - let scale_before_cvt = is_better_fmt(&ifmt, &ofmt) && needs_convert + let scale_before_cvt = is_better_fmt(ifmt, ofmt) && needs_convert && (ofmt.fmt.get_max_subsampling() == 0); let needs_palettise = ofmt.fmt.palette; //todo stages for model and gamma conversion @@ -296,9 +296,9 @@ fn build_pipeline(ifmt: &ScaleInfo, ofmt: &ScaleInfo, just_convert: bool, option println!("[adding unpack]"); } let new_stage = if !cur_fmt.fmt.is_paletted() { - Stage::new("unpack", &cur_fmt, &ofmt, options)? + Stage::new("unpack", &cur_fmt, ofmt, options)? } else { - Stage::new("depal", &cur_fmt, &ofmt, options)? + Stage::new("depal", &cur_fmt, ofmt, options)? }; cur_fmt = new_stage.fmt_out; add_stage!(stages, new_stage); @@ -307,7 +307,7 @@ fn build_pipeline(ifmt: &ScaleInfo, ofmt: &ScaleInfo, just_convert: bool, option if debug { println!("[adding scale]"); } - let new_stage = Stage::new("scale", &cur_fmt, &ofmt, options)?; + let new_stage = Stage::new("scale", &cur_fmt, ofmt, options)?; cur_fmt = new_stage.fmt_out; add_stage!(stages, new_stage); } @@ -319,7 +319,7 @@ fn build_pipeline(ifmt: &ScaleInfo, ofmt: &ScaleInfo, just_convert: bool, option if debug { println!("[{}]", cvtname); } - let new_stage = Stage::new(&cvtname, &cur_fmt, &ofmt, options)?; + let new_stage = Stage::new(&cvtname, &cur_fmt, ofmt, options)?; //todo if fails try converting via RGB or YUV cur_fmt = new_stage.fmt_out; add_stage!(stages, new_stage); @@ -329,7 +329,7 @@ fn build_pipeline(ifmt: &ScaleInfo, ofmt: &ScaleInfo, just_convert: bool, option if debug { println!("[adding scale]"); } - let new_stage = Stage::new("scale", &cur_fmt, &ofmt, options)?; + let new_stage = Stage::new("scale", &cur_fmt, ofmt, options)?; cur_fmt = new_stage.fmt_out; add_stage!(stages, new_stage); } @@ -337,7 +337,7 @@ fn build_pipeline(ifmt: &ScaleInfo, ofmt: &ScaleInfo, just_convert: bool, option if debug { println!("[adding pack]"); } - let new_stage = Stage::new("pack", &cur_fmt, &ofmt, options)?; + let new_stage = Stage::new("pack", &cur_fmt, ofmt, options)?; //cur_fmt = new_stage.fmt_out; add_stage!(stages, new_stage); } @@ -345,7 +345,7 @@ fn build_pipeline(ifmt: &ScaleInfo, ofmt: &ScaleInfo, just_convert: bool, option if debug { println!("[adding palettise]"); } - let new_stage = Stage::new("palette", &cur_fmt, &ofmt, options)?; + let new_stage = Stage::new("palette", &cur_fmt, ofmt, options)?; //cur_fmt = new_stage.fmt_out; add_stage!(stages, new_stage); } @@ -363,8 +363,8 @@ fn swap_plane(data: &mut [T], stride: usize, h: usize, line0: &mut [T], for _ in 0..h/2 { line0.copy_from_slice(&data[doff0..][..stride]); line1.copy_from_slice(&data[doff1..][..stride]); - (&mut data[doff1..][..stride]).copy_from_slice(line0); - (&mut data[doff0..][..stride]).copy_from_slice(line1); + data[doff1..][..stride].copy_from_slice(line0); + data[doff0..][..stride].copy_from_slice(line1); doff0 += stride; doff1 -= stride; } @@ -438,24 +438,22 @@ pub fn flip_picture(pic: &mut NABufferType) -> ScaleResult<()> { impl NAScale { /// Constructs a new `NAScale` instance. pub fn new(fmt_in: ScaleInfo, fmt_out: ScaleInfo) -> ScaleResult { - let pipeline; let just_convert = (fmt_in.width == fmt_out.width) && (fmt_in.height == fmt_out.height); - if fmt_in != fmt_out { - pipeline = build_pipeline(&fmt_in, &fmt_out, just_convert, &[])?; - } else { - pipeline = None; - } + let pipeline = if fmt_in != fmt_out { + build_pipeline(&fmt_in, &fmt_out, just_convert, &[])? + } else { + None + }; Ok(Self { fmt_in, fmt_out, just_convert, pipeline }) } /// Constructs a new `NAScale` instance taking into account provided options. pub fn new_with_options(fmt_in: ScaleInfo, fmt_out: ScaleInfo, options: &[(String, String)]) -> ScaleResult { - let pipeline; let just_convert = (fmt_in.width == fmt_out.width) && (fmt_in.height == fmt_out.height); - if fmt_in != fmt_out { - pipeline = build_pipeline(&fmt_in, &fmt_out, just_convert, options)?; - } else { - pipeline = None; - } + let pipeline = if fmt_in != fmt_out { + build_pipeline(&fmt_in, &fmt_out, just_convert, options)? + } else { + None + }; Ok(Self { fmt_in, fmt_out, just_convert, pipeline }) } /// Checks whether requested conversion operation is needed at all. @@ -597,4 +595,60 @@ mod test { assert_eq!(odata[paloff + 1], 129); assert_eq!(odata[paloff + 2], 170); } + #[test] + fn test_scale_modes() { + const IN_DATA: [[u8; 6]; 2] = [ + [0xFF, 0xC0, 0x40, 0x00, 0x40, 0xC0], + [0x00, 0x40, 0xC0, 0xFF, 0xC0, 0x40] + ]; + const TEST_DATA: &[(&str, [[u8; 9]; 3])] = &[ + ("nn", + [[0xFF, 0xC0, 0x40, 0xFF, 0xC0, 0x40, 0x00, 0x40, 0xC0], + [0xFF, 0xC0, 0x40, 0xFF, 0xC0, 0x40, 0x00, 0x40, 0xC0], + [0x00, 0x40, 0xC0, 0x00, 0x40, 0xC0, 0xFF, 0xC0, 0x40]]), + ("bilin", + [[0xFF, 0xC0, 0x40, 0x55, 0x6A, 0x95, 0x00, 0x40, 0xC0], + [0x55, 0x6A, 0x95, 0x8D, 0x86, 0x78, 0xAA, 0x95, 0x6A], + [0x00, 0x40, 0xC0, 0xAA, 0x95, 0x6A, 0xFF, 0xC0, 0x40]]), + ("bicubic", + [[0xFF, 0xC0, 0x40, 0x4B, 0x65, 0x9A, 0x00, 0x36, 0xC9], + [0x4B, 0x65, 0x9A, 0x94, 0x8A, 0x74, 0xB3, 0x9D, 0x61], + [0x00, 0x36, 0xC9, 0xBA, 0x9D, 0x61, 0xFF, 0xD3, 0x2B]]), + ("lanczos", + [[0xFF, 0xC0, 0x40, 0x4C, 0x66, 0x98, 0x00, 0x31, 0xCD], + [0x4C, 0x66, 0x98, 0x91, 0x88, 0x74, 0xB1, 0x9D, 0x5F], + [0x00, 0x31, 0xCD, 0xBB, 0x9D, 0x5F, 0xFF, 0xDD, 0x1E]]), + ("lanczos2", + [[0xFF, 0xC0, 0x40, 0x4F, 0x68, 0x9B, 0x00, 0x35, 0xCD], + [0x4F, 0x68, 0x9B, 0x96, 0x8D, 0x79, 0xB3, 0xA0, 0x64], + [0x00, 0x35, 0xCD, 0xBE, 0xA1, 0x65, 0xFF, 0xDC, 0x28]]), + ]; + + let in_pic = alloc_video_buffer(NAVideoInfo::new(2, 2, false, RGB24_FORMAT), 3).unwrap(); + if let Some(ref mut vbuf) = in_pic.get_vbuf() { + let stride = vbuf.get_stride(0); + let data = vbuf.get_data_mut().unwrap(); + for (dline, rline) in data.chunks_mut(stride).zip(IN_DATA.iter()) { + dline[..6].copy_from_slice(rline); + } + } else { + panic!("wrong format"); + } + let mut out_pic = alloc_video_buffer(NAVideoInfo::new(3, 3, false, RGB24_FORMAT), 3).unwrap(); + let ifmt = get_scale_fmt_from_pic(&in_pic); + let ofmt = get_scale_fmt_from_pic(&out_pic); + for (method, ref_data) in TEST_DATA.iter() { + fill_pic(&mut out_pic, 0); + let mut scaler = NAScale::new_with_options(ifmt, ofmt, &[("scaler".to_string(), method.to_string())]).unwrap(); + scaler.convert(&in_pic, &mut out_pic).unwrap(); + let obuf = out_pic.get_vbuf().unwrap(); + let ostride = obuf.get_stride(0); + let odata = obuf.get_data(); + for (oline, rline) in odata.chunks(ostride).zip(ref_data.iter()) { + for (&a, &b) in oline.iter().zip(rline.iter()) { + assert_eq!(a, b); + } + } + } + } }