]>
Commit | Line | Data |
---|---|---|
03accf76 KS |
1 | use super::*; |
2 | use super::kernel::Kernel; | |
3 | ||
4 | struct NNResampler {} | |
5 | ||
6 | impl NNResampler { | |
7 | fn new() -> Self { Self{} } | |
8 | } | |
9 | ||
1ffd44c8 KS |
10 | fn scale_line<T:Copy>(src: &[T], dst: &mut [T], src_w: usize, dst_w: usize) { |
11 | if src_w == dst_w { | |
12 | (&mut dst[..dst_w]).copy_from_slice(&src[..dst_w]); | |
13 | } else if src_w < dst_w { | |
14 | if dst_w % src_w == 0 { | |
15 | let step = dst_w / src_w; | |
16 | for (out, srcv) in dst.chunks_exact_mut(step).take(src_w).zip(src.iter()) { | |
17 | for el in out.iter_mut() { | |
18 | *el = *srcv; | |
19 | } | |
20 | } | |
21 | } else { | |
22 | let mut pos = 0; | |
23 | for out in dst.iter_mut().take(dst_w) { | |
24 | *out = src[pos / dst_w]; | |
25 | pos += src_w; | |
26 | } | |
27 | } | |
28 | } else { | |
29 | if dst_w % src_w == 0 { | |
30 | let step = src_w / dst_w; | |
31 | for (out, srcv) in dst.iter_mut().take(dst_w).zip(src.iter().step_by(step)) { | |
32 | *out = *srcv; | |
33 | } | |
34 | } else { | |
35 | let mut pos = 0; | |
36 | for out in dst.iter_mut().take(dst_w) { | |
37 | *out = src[pos / dst_w]; | |
38 | pos += src_w; | |
39 | } | |
40 | } | |
41 | } | |
42 | } | |
43 | ||
03accf76 KS |
44 | macro_rules! scale_loop { |
45 | ($sbuf:expr, $dbuf:expr) => { | |
46 | let fmt = $sbuf.get_info().get_format(); | |
47 | let ncomp = fmt.get_num_comp(); | |
48 | for comp in 0..ncomp { | |
49 | let istride = $sbuf.get_stride(comp); | |
50 | let dstride = $dbuf.get_stride(comp); | |
51 | let (sw, sh) = $sbuf.get_dimensions(comp); | |
52 | let (dw, dh) = $dbuf.get_dimensions(comp); | |
53 | let ioff = $sbuf.get_offset(comp); | |
54 | let mut doff = $dbuf.get_offset(comp); | |
55 | let src = $sbuf.get_data(); | |
56 | let dst = $dbuf.get_data_mut().unwrap(); | |
57 | for y in 0..dh { | |
58 | let sy = y * sh / dh; | |
59 | let soff = ioff + sy * istride; | |
1ffd44c8 | 60 | scale_line(&src[soff..], &mut dst[doff..], sw, dw); |
03accf76 KS |
61 | doff += dstride; |
62 | } | |
63 | } | |
64 | }; | |
65 | } | |
66 | ||
67 | impl Kernel for NNResampler { | |
68 | fn init(&mut self, in_fmt: &ScaleInfo, dest_fmt: &ScaleInfo) -> ScaleResult<NABufferType> { | |
69 | let res = alloc_video_buffer(NAVideoInfo::new(dest_fmt.width, dest_fmt.height, false, in_fmt.fmt), 3); | |
70 | if res.is_err() { return Err(ScaleError::AllocError); } | |
71 | Ok(res.unwrap()) | |
72 | } | |
73 | fn process(&mut self, pic_in: &NABufferType, pic_out: &mut NABufferType) { | |
74 | if let (Some(ref sbuf), Some(ref mut dbuf)) = (pic_in.get_vbuf(), pic_out.get_vbuf()) { | |
75 | scale_loop!(sbuf, dbuf); | |
76 | } else if let (Some(ref sbuf), Some(ref mut dbuf)) = (pic_in.get_vbuf16(), pic_out.get_vbuf16()) { | |
77 | scale_loop!(sbuf, dbuf); | |
78 | } else if let (Some(ref sbuf), Some(ref mut dbuf)) = (pic_in.get_vbuf32(), pic_out.get_vbuf32()) { | |
79 | scale_loop!(sbuf, dbuf); | |
80 | } else { | |
81 | unreachable!(); | |
82 | } | |
83 | } | |
84 | } | |
85 | ||
6011e201 | 86 | pub fn create_scale() -> Box<dyn Kernel> { |
03accf76 KS |
87 | Box::new(NNResampler::new()) |
88 | } | |
89 |