]>
Commit | Line | Data |
---|---|---|
aca89041 | 1 | use crate::frame::*; |
cf64af13 KS |
2 | |
3 | pub fn put_blocks(buf: &mut NAVideoBuffer<u8>, xpos: usize, ypos: usize, blk: &[[i16;64]; 6]) { | |
4 | let stridey = buf.get_stride(0); | |
5 | let strideu = buf.get_stride(1); | |
6 | let stridev = buf.get_stride(2); | |
7 | let mut idxy = buf.get_offset(0) + xpos * 16 + ypos * 16 * stridey; | |
8 | let mut idxu = buf.get_offset(1) + xpos * 8 + ypos * 8 * strideu; | |
9 | let mut idxv = buf.get_offset(2) + xpos * 8 + ypos * 8 * stridev; | |
10 | ||
1a967e6b | 11 | let data = buf.get_data_mut().unwrap(); |
9037cf6b | 12 | let framebuf: &mut [u8] = data.as_mut_slice(); |
cf64af13 KS |
13 | |
14 | for j in 0..8 { | |
15 | for k in 0..8 { | |
16 | let mut v = blk[0][k + j * 8]; | |
e243ceb4 | 17 | if v < 0 { v = 0; } else if v > 255 { v = 255; } |
cf64af13 KS |
18 | framebuf[idxy + k] = v as u8; |
19 | } | |
20 | for k in 0..8 { | |
21 | let mut v = blk[1][k + j * 8]; | |
e243ceb4 | 22 | if v < 0 { v = 0; } else if v > 255 { v = 255; } |
cf64af13 KS |
23 | framebuf[idxy + k + 8] = v as u8; |
24 | } | |
25 | idxy += stridey; | |
26 | } | |
27 | for j in 0..8 { | |
28 | for k in 0..8 { | |
29 | let mut v = blk[2][k + j * 8]; | |
e243ceb4 | 30 | if v < 0 { v = 0; } else if v > 255 { v = 255; } |
cf64af13 KS |
31 | framebuf[idxy + k] = v as u8; |
32 | } | |
33 | for k in 0..8 { | |
34 | let mut v = blk[3][k + j * 8]; | |
e243ceb4 | 35 | if v < 0 { v = 0; } else if v > 255 { v = 255; } |
cf64af13 KS |
36 | framebuf[idxy + k + 8] = v as u8; |
37 | } | |
38 | idxy += stridey; | |
39 | } | |
40 | ||
41 | for j in 0..8 { | |
42 | for k in 0..8 { | |
43 | let mut v = blk[4][k + j * 8]; | |
e243ceb4 | 44 | if v < 0 { v = 0; } else if v > 255 { v = 255; } |
cf64af13 KS |
45 | framebuf[idxu + k] = v as u8; |
46 | } | |
47 | for k in 0..8 { | |
48 | let mut v = blk[5][k + j * 8]; | |
e243ceb4 | 49 | if v < 0 { v = 0; } else if v > 255 { v = 255; } |
cf64af13 KS |
50 | framebuf[idxv + k] = v as u8; |
51 | } | |
52 | idxu += strideu; | |
53 | idxv += stridev; | |
54 | } | |
55 | } | |
56 | ||
57 | pub fn add_blocks(buf: &mut NAVideoBuffer<u8>, xpos: usize, ypos: usize, blk: &[[i16;64]; 6]) { | |
58 | let stridey = buf.get_stride(0); | |
59 | let strideu = buf.get_stride(1); | |
60 | let stridev = buf.get_stride(2); | |
61 | let mut idxy = buf.get_offset(0) + xpos * 16 + ypos * 16 * stridey; | |
62 | let mut idxu = buf.get_offset(1) + xpos * 8 + ypos * 8 * strideu; | |
63 | let mut idxv = buf.get_offset(2) + xpos * 8 + ypos * 8 * stridev; | |
64 | ||
1a967e6b | 65 | let data = buf.get_data_mut().unwrap(); |
9037cf6b | 66 | let framebuf: &mut [u8] = data.as_mut_slice(); |
cf64af13 KS |
67 | |
68 | for j in 0..8 { | |
69 | for k in 0..8 { | |
e243ceb4 KS |
70 | let mut v = blk[0][k + j * 8] + i16::from(framebuf[idxy + k]); |
71 | if v < 0 { v = 0; } else if v > 255 { v = 255; } | |
cf64af13 KS |
72 | framebuf[idxy + k] = v as u8; |
73 | } | |
74 | for k in 0..8 { | |
e243ceb4 KS |
75 | let mut v = blk[1][k + j * 8] + i16::from(framebuf[idxy + k + 8]); |
76 | if v < 0 { v = 0; } else if v > 255 { v = 255; } | |
cf64af13 KS |
77 | framebuf[idxy + k + 8] = v as u8; |
78 | } | |
79 | idxy += stridey; | |
80 | } | |
81 | for j in 0..8 { | |
82 | for k in 0..8 { | |
e243ceb4 KS |
83 | let mut v = blk[2][k + j * 8] + i16::from(framebuf[idxy + k]); |
84 | if v < 0 { v = 0; } else if v > 255 { v = 255; } | |
cf64af13 KS |
85 | framebuf[idxy + k] = v as u8; |
86 | } | |
87 | for k in 0..8 { | |
e243ceb4 KS |
88 | let mut v = blk[3][k + j * 8] + i16::from(framebuf[idxy + k + 8]); |
89 | if v < 0 { v = 0; } else if v > 255 { v = 255; } | |
cf64af13 KS |
90 | framebuf[idxy + k + 8] = v as u8; |
91 | } | |
92 | idxy += stridey; | |
93 | } | |
94 | ||
95 | for j in 0..8 { | |
96 | for k in 0..8 { | |
e243ceb4 KS |
97 | let mut v = blk[4][k + j * 8] + i16::from(framebuf[idxu + k]); |
98 | if v < 0 { v = 0; } else if v > 255 { v = 255; } | |
cf64af13 KS |
99 | framebuf[idxu + k] = v as u8; |
100 | } | |
101 | for k in 0..8 { | |
e243ceb4 KS |
102 | let mut v = blk[5][k + j * 8] + i16::from(framebuf[idxv + k]); |
103 | if v < 0 { v = 0; } else if v > 255 { v = 255; } | |
cf64af13 KS |
104 | framebuf[idxv + k] = v as u8; |
105 | } | |
106 | idxu += strideu; | |
107 | idxv += stridev; | |
108 | } | |
109 | } | |
110 | ||
47527732 | 111 | pub fn edge_emu(src: &NAVideoBuffer<u8>, xpos: isize, ypos: isize, bw: usize, bh: usize, dst: &mut [u8], dstride: usize, comp: usize) { |
cf64af13 KS |
112 | let stride = src.get_stride(comp); |
113 | let offs = src.get_offset(comp); | |
114 | let (w, h) = src.get_dimensions(comp); | |
115 | let data = src.get_data(); | |
116 | let framebuf: &[u8] = data.as_slice(); | |
117 | ||
118 | for y in 0..bh { | |
119 | let srcy; | |
120 | if (y as isize) + ypos < 0 { srcy = 0; } | |
121 | else if (y as isize) + ypos >= (h as isize) { srcy = h - 1; } | |
122 | else { srcy = ((y as isize) + ypos) as usize; } | |
123 | ||
124 | for x in 0..bw { | |
125 | let srcx; | |
126 | if (x as isize) + xpos < 0 { srcx = 0; } | |
127 | else if (x as isize) + xpos >= (w as isize) { srcx = w - 1; } | |
128 | else { srcx = ((x as isize) + xpos) as usize; } | |
129 | dst[x + y * dstride] = framebuf[offs + srcx + srcy * stride]; | |
130 | } | |
131 | } | |
132 | } | |
133 | ||
fdb4b2fb KS |
134 | pub type BlkInterpFunc = fn(&mut [u8], usize, &[u8], usize, usize, usize); |
135 | ||
cf64af13 KS |
136 | pub fn copy_blocks(dst: &mut NAVideoBuffer<u8>, src: &NAVideoBuffer<u8>, |
137 | dx: usize, dy: usize, sx: isize, sy: isize, bw: usize, bh: usize, | |
138 | preborder: usize, postborder: usize, | |
fdb4b2fb | 139 | mode: usize, interp: &[BlkInterpFunc]) |
cf64af13 KS |
140 | { |
141 | let pre = if mode != 0 { preborder as isize } else { 0 }; | |
142 | let post = if mode != 0 { postborder as isize } else { 0 }; | |
143 | let (w, h) = src.get_dimensions(0); | |
144 | ||
145 | if (sx - pre < 0) || ((sx >> 1) - pre < 0) || (sx + (bw as isize) + post > (w as isize)) || | |
146 | (sy - pre < 0) || ((sy >> 1) - pre < 0) || (sy + (bh as isize) + post > (h as isize)) { | |
147 | let ebuf_stride: usize = 32; | |
e243ceb4 | 148 | let mut ebuf: Vec<u8> = vec![0; ebuf_stride * (bh + ((pre + post) as usize))]; |
cf64af13 KS |
149 | |
150 | for comp in 0..3 { | |
2bfdf329 | 151 | let dstride = dst.get_stride(comp); |
cf64af13 | 152 | let doff = dst.get_offset(comp); |
1a967e6b | 153 | let ddta = dst.get_data_mut().unwrap(); |
4a9d2671 | 154 | let dbuf: &mut [u8] = ddta.as_mut_slice(); |
cf64af13 KS |
155 | let x = if comp > 0 { dx/2 } else { dx }; |
156 | let y = if comp > 0 { dy/2 } else { dy }; | |
157 | let sx_ = (if comp > 0 { sx >> 1 } else { sx }) - pre; | |
158 | let sy_ = (if comp > 0 { sy >> 1 } else { sy }) - pre; | |
159 | let bw_ = (if comp > 0 { bw/2 } else { bw }) + ((pre + post) as usize); | |
160 | let bh_ = (if comp > 0 { bh/2 } else { bh }) + ((pre + post) as usize); | |
161 | edge_emu(src, sx_ - pre, sy_ - pre, bw_, bh_, | |
162 | ebuf.as_mut_slice(), ebuf_stride, comp); | |
163 | let bw_ = if comp > 0 { bw/2 } else { bw }; | |
164 | let bh_ = if comp > 0 { bh/2 } else { bh }; | |
165 | (interp[mode])(&mut dbuf[doff + x + y * dstride..], dstride, ebuf.as_slice(), ebuf_stride, bw_, bh_); | |
166 | } | |
cf64af13 KS |
167 | } else { |
168 | for comp in 0..3 { | |
169 | let sstride = src.get_stride(comp); | |
170 | let soff = src.get_offset(comp); | |
171 | let sdta = src.get_data(); | |
172 | let sbuf: &[u8] = sdta.as_slice(); | |
2bfdf329 | 173 | let dstride = dst.get_stride(comp); |
cf64af13 | 174 | let doff = dst.get_offset(comp); |
1a967e6b | 175 | let ddta = dst.get_data_mut().unwrap(); |
4a9d2671 | 176 | let dbuf: &mut [u8] = ddta.as_mut_slice(); |
cf64af13 KS |
177 | let x = if comp > 0 { dx/2 } else { dx }; |
178 | let y = if comp > 0 { dy/2 } else { dy }; | |
179 | let sx_ = ((if comp > 0 { sx >> 1 } else { sx }) - pre) as usize; | |
180 | let sy_ = ((if comp > 0 { sy >> 1 } else { sy }) - pre) as usize; | |
181 | let bw_ = if comp > 0 { bw/2 } else { bw }; | |
182 | let bh_ = if comp > 0 { bh/2 } else { bh }; | |
183 | (interp[mode])(&mut dbuf[doff + x + y * dstride..], dstride, &sbuf[(soff + sx_ + sy_ * sstride)..], sstride, bw_, bh_); | |
184 | } | |
185 | } | |
186 | } | |
c6670064 KS |
187 | |
188 | pub fn copy_block(dst: &mut NASimpleVideoFrame<u8>, src: NAVideoBufferRef<u8>, comp: usize, | |
189 | dx: usize, dy: usize, mv_x: i16, mv_y: i16, bw: usize, bh: usize, | |
190 | preborder: usize, postborder: usize, | |
191 | mode: usize, interp: &[BlkInterpFunc]) | |
192 | { | |
193 | let pre = if mode != 0 { preborder as isize } else { 0 }; | |
194 | let post = if mode != 0 { postborder as isize } else { 0 }; | |
195 | let (w, h) = src.get_dimensions(comp); | |
196 | let sx = (dx as isize) + (mv_x as isize); | |
197 | let sy = (dy as isize) + (mv_y as isize); | |
198 | ||
199 | if (sx - pre < 0) || (sx + (bw as isize) + post > (w as isize)) || | |
200 | (sy - pre < 0) || (sy + (bh as isize) + post > (h as isize)) { | |
201 | let ebuf_stride: usize = 32; | |
202 | let mut ebuf: Vec<u8> = vec![0; ebuf_stride * (bh + ((pre + post) as usize))]; | |
203 | ||
204 | let dstride = dst.stride[comp]; | |
205 | let doff = dst.offset[comp]; | |
206 | let edge = (pre + post) as usize; | |
207 | edge_emu(&src, sx - pre, sy - pre, bw + edge, bh + edge, | |
208 | ebuf.as_mut_slice(), ebuf_stride, comp); | |
209 | (interp[mode])(&mut dst.data[doff + dx + dy * dstride..], dstride, | |
210 | ebuf.as_slice(), ebuf_stride, bw, bh); | |
211 | } else { | |
212 | let sstride = src.get_stride(comp); | |
213 | let soff = src.get_offset(comp); | |
214 | let sdta = src.get_data(); | |
215 | let sbuf: &[u8] = sdta.as_slice(); | |
216 | let dstride = dst.stride[comp]; | |
217 | let doff = dst.offset[comp]; | |
218 | let saddr = soff + ((sx - pre) as usize) + ((sy - pre) as usize) * sstride; | |
219 | (interp[mode])(&mut dst.data[doff + dx + dy * dstride..], dstride, | |
220 | &sbuf[saddr..], sstride, bw, bh); | |
221 | } | |
222 | } |