]> git.nihav.org Git - nihav.git/blame - nihav-realmedia/src/codecs/rv40enc/dsp/ipred.rs
avimux: do not record palette change chunks in OpenDML index
[nihav.git] / nihav-realmedia / src / codecs / rv40enc / dsp / ipred.rs
CommitLineData
4965a5e5
KS
1use super::super::types::{PredType8x8, PredType4x4};
2use super::RefMBData;
3
4#[derive(Default)]
5pub struct IntraPred16x16 {
6 pub top: [u8; 17],
7 pub left: [u8; 17],
8}
9
10impl IntraPred16x16 {
11 pub fn new() -> Self { Self::default() }
12 #[allow(clippy::many_single_char_names)]
13 pub fn apply16(&self, mode: PredType8x8, dst: &mut [u8], stride: usize) {
14 match mode {
15 PredType8x8::DC => {
16 let sumt = self.top[1..].iter().fold(0u32, |acc, &x| acc + u32::from(x));
17 let suml = self.left[1..].iter().fold(0u32, |acc, &x| acc + u32::from(x));
18 let dc = ((sumt + suml + 16) >> 5) as u8;
19 for line in dst.chunks_mut(stride).take(16) {
20 for dst in line[..16].iter_mut() {
21 *dst = dc;
22 }
23 }
24 },
25 PredType8x8::Hor => {
26 for (&left, line) in self.left[1..].iter().zip(dst.chunks_mut(stride)) {
27 for dst in line[..16].iter_mut() {
28 *dst = left;
29 }
30 }
31 },
32 PredType8x8::Ver => {
33 for line in dst.chunks_mut(stride).take(16) {
34 line[..16].copy_from_slice(&self.top[1..]);
35 }
36 },
37 PredType8x8::Plane => {
38 let top0 = &self.top[9..];
39 let top1 = &self.top[..8];
40 let h = top0.iter().zip(top1.iter().rev()).enumerate().fold(
41 0i32, |acc, (k, (&a, &b))| acc + ((k + 1) as i32) * (i32::from(a) - i32::from(b)));
42 let left0 = &self.left[9..];
43 let left1 = &self.left[..8];
44 let v = left0.iter().zip(left1.iter().rev()).enumerate().fold(
45 0i32, |acc, (k, (&a, &b))| acc + ((k + 1) as i32) * (i32::from(a) - i32::from(b)));
46 let b = (h + (h >> 2)) >> 4;
47 let c = (v + (v >> 2)) >> 4;
48 let mut a = 16 * (i32::from(self.left[16]) + i32::from(self.top[16])) + 16 - 7 * (b + c);
49
50 for line in dst.chunks_mut(stride).take(16) {
51 let mut oval = a;
52 for el in line[..16].iter_mut() {
53 *el = (oval >> 5).max(0).min(255) as u8;
54 oval += b;
55 }
56 a += c;
57 }
58 },
59 PredType8x8::LeftDC => {
60 let dc = ((self.left[1..].iter().fold(0u32, |acc, &x| acc + u32::from(x)) + 8) >> 4) as u8;
61 for line in dst.chunks_mut(stride).take(16) {
62 for dst in line[..16].iter_mut() {
63 *dst = dc;
64 }
65 }
66 },
67 PredType8x8::TopDC => {
68 let dc = ((self.top[1..].iter().fold(0u32, |acc, &x| acc + u32::from(x)) + 8) >> 4) as u8;
69 for line in dst.chunks_mut(stride).take(16) {
70 for dst in line[..16].iter_mut() {
71 *dst = dc;
72 }
73 }
74 },
75 PredType8x8::DC128 => {
76 for line in dst.chunks_mut(stride).take(16) {
77 for dst in line[..16].iter_mut() {
78 *dst = 128;
79 }
80 }
81 },
82 }
83 }
84 pub fn apply8(&self, mode: PredType8x8, dst: &mut [u8], stride: usize) {
85 match mode {
86 PredType8x8::DC | PredType8x8::Plane => {
87 let sumt = self.top[1..9].iter().fold(0u32, |acc, &x| acc + u32::from(x));
88 let suml = self.left[1..9].iter().fold(0u32, |acc, &x| acc + u32::from(x));
89 let dc = ((sumt + suml + 8) >> 4) as u8;
90 for line in dst.chunks_mut(stride).take(8) {
91 for dst in line[..8].iter_mut() {
92 *dst = dc;
93 }
94 }
95 },
96 PredType8x8::Hor => {
97 for (&left, line) in self.left[1..9].iter().zip(dst.chunks_mut(stride)) {
98 for dst in line[..8].iter_mut() {
99 *dst = left;
100 }
101 }
102 },
103 PredType8x8::Ver => {
104 for line in dst.chunks_mut(stride).take(8) {
105 line[..8].copy_from_slice(&self.top[1..9]);
106 }
107 },
108 PredType8x8::LeftDC => {
109 let dc = ((self.left[1..9].iter().fold(0u32, |acc, &x| acc + u32::from(x)) + 4) >> 3) as u8;
110 for line in dst.chunks_mut(stride).take(8) {
111 for dst in line[..8].iter_mut() {
112 *dst = dc;
113 }
114 }
115 },
116 PredType8x8::TopDC => {
117 let dc = ((self.top[1..9].iter().fold(0u32, |acc, &x| acc + u32::from(x)) + 4) >> 3) as u8;
118 for line in dst.chunks_mut(stride).take(8) {
119 for dst in line[..8].iter_mut() {
120 *dst = dc;
121 }
122 }
123 },
124 PredType8x8::DC128 => {
125 for line in dst.chunks_mut(stride).take(8) {
126 for dst in line[..8].iter_mut() {
127 *dst = 128;
128 }
129 }
130 },
131 }
132 }
133}
134
135#[derive(Default)]
136pub struct Intra4Pred {
137 pub top: [u8; 8],
138 pub left: [u8; 8],
139 pub tl: u8,
140}
141
142impl Intra4Pred {
143 pub fn new() -> Self { Self::default() }
144 fn load_left(&self) -> [u16; 8] {
145 let mut ret = [0; 8];
146 for (dst, &src) in ret.iter_mut().zip(self.left.iter()) {
147 *dst = u16::from(src);
148 }
149 ret
150 }
151 fn load_top(&self) -> [u16; 8] {
152 let mut ret = [0; 8];
153 for (dst, &src) in ret.iter_mut().zip(self.top.iter()) {
154 *dst = u16::from(src);
155 }
156 ret
157 }
158 fn load_left_and_top(&self) -> ([u16; 5], [u16; 5]) {
159 let mut left = [0; 5];
160 let mut top = [0; 5];
161 left[0] = u16::from(self.tl);
162 top[0] = u16::from(self.tl);
163 for (dst, &src) in left[1..].iter_mut().zip(self.left.iter()) {
164 *dst = u16::from(src);
165 }
166 for (dst, &src) in top[1..].iter_mut().zip(self.top.iter()) {
167 *dst = u16::from(src);
168 }
169 (left, top)
170 }
d92111a8 171 #[allow(clippy::collapsible_else_if)]
4965a5e5
KS
172 #[allow(clippy::many_single_char_names)]
173 pub fn apply(&self, ptype: PredType4x4, buf: &mut [u8], stride: usize) {
174 match ptype {
175 PredType4x4::DC => {
176 let dc_l = self.left[..4].iter().fold(0u32, |acc, &x| acc + u32::from(x));
177 let dc_t = self.top [..4].iter().fold(0u32, |acc, &x| acc + u32::from(x));
178 let dc = ((dc_t + dc_l + 4) >> 3) as u8;
179 for line in buf.chunks_mut(stride).take(4) {
180 for el in line[..4].iter_mut() {
181 *el = dc;
182 }
183 }
184 },
185 PredType4x4::LeftDC => {
186 let dc_l = self.left[..4].iter().fold(0u32, |acc, &x| acc + u32::from(x));
187 let dc = ((dc_l + 2) >> 2) as u8;
188 for line in buf.chunks_mut(stride).take(4) {
189 for el in line[..4].iter_mut() {
190 *el = dc;
191 }
192 }
193 },
194 PredType4x4::TopDC => {
195 let dc_t = self.top [..4].iter().fold(0u32, |acc, &x| acc + u32::from(x));
196 let dc = ((dc_t + 2) >> 2) as u8;
197 for line in buf.chunks_mut(stride).take(4) {
198 for el in line[..4].iter_mut() {
199 *el = dc;
200 }
201 }
202 },
203 PredType4x4::DC128 => {
204 for line in buf.chunks_mut(stride).take(4) {
205 for el in line[..4].iter_mut() {
206 *el = 128;
207 }
208 }
209 },
210 PredType4x4::Ver => {
211 for line in buf.chunks_mut(stride).take(4) {
212 line[..4].copy_from_slice(&self.top[..4]);
213 }
214 },
215 PredType4x4::Hor => {
216 for (&left, line) in self.left[..4].iter().zip(buf.chunks_mut(stride)) {
217 for dst in line[..4].iter_mut() {
218 *dst = left;
219 }
220 }
221 },
222 PredType4x4::DiagDownLeft => {
223 let l = self.load_left();
224 let t = self.load_top();
225 buf[0] = ((t[0] + t[2] + 2*t[1] + 2 + l[0] + l[2] + 2*l[1] + 2) >> 3) as u8;
226 let pix = ((t[1] + t[3] + 2*t[2] + 2 + l[1] + l[3] + 2*l[2] + 2) >> 3) as u8;
227 buf[1] = pix;
228 buf[stride] = pix;
229 let pix = ((t[2] + t[4] + 2*t[3] + 2 + l[2] + l[4] + 2*l[3] + 2) >> 3) as u8;
230 buf[2] = pix;
231 buf[1 + stride] = pix;
232 buf[2 * stride] = pix;
233 let pix = ((t[3] + t[5] + 2*t[4] + 2 + l[3] + l[5] + 2*l[4] + 2) >> 3) as u8;
234 buf[3] = pix;
235 buf[2 + stride] = pix;
236 buf[1 + 2 * stride] = pix;
237 buf[ 3 * stride] = pix;
238 let pix = ((t[4] + t[6] + 2*t[5] + 2 + l[4] + l[6] + 2*l[5] + 2) >> 3) as u8;
239 buf[3 + stride] = pix;
240 buf[2 + 2 * stride] = pix;
241 buf[1 + 3 * stride] = pix;
242 let pix = ((t[5] + t[7] + 2*t[6] + 2 + l[5] + l[7] + 2*l[6] + 2) >> 3) as u8;
243 buf[3 + 2 * stride] = pix;
244 buf[2 + 3 * stride] = pix;
245 buf[3 + 3 * stride] = ((t[6] + t[7] + 1 + l[6] + l[7] + 1) >> 2) as u8;
246 },
247 PredType4x4::DiagDownRight => {
248 let (l, t) = self.load_left_and_top();
249 for (j, line) in buf.chunks_mut(stride).take(4).enumerate() {
250 for i in 0..j {
251 line[i] = ((l[j - i - 1] + 2 * l[j - i] + l[j - i + 1] + 2) >> 2) as u8;
252 }
253 line[j] = ((l[1] + 2 * l[0] + t[1] + 2) >> 2) as u8;
254 for i in (j + 1)..4 {
255 line[i] = ((t[i - j - 1] + 2 * t[i - j] + t[i - j + 1] + 2) >> 2) as u8;
256 }
257 }
258 },
259 PredType4x4::VerRight => {
260 let (l, t) = self.load_left_and_top();
261 for (j, line) in buf.chunks_mut(stride).take(4).enumerate() {
262 for (i, pix) in line[..4].iter_mut().enumerate() {
263 let zvr = ((2 * i) as i8) - (j as i8);
264 *pix = if zvr >= 0 {
265 if (zvr & 1) == 0 {
266 (t[i - (j >> 1)] + t[i - (j >> 1) + 1] + 1) >> 1
267 } else {
268 (t[i - (j >> 1) - 1] + 2 * t[i - (j >> 1)] + t[i - (j >> 1) + 1] + 2) >> 2
269 }
270 } else {
271 if zvr == -1 {
272 (l[1] + 2 * l[0] + t[1] + 2) >> 2
273 } else {
274 (l[j] + 2 * l[j - 1] + l[j - 2] + 2) >> 2
275 }
276 } as u8;
277 }
278 }
279 },
280 PredType4x4::HorDown => {
281 let (l, t) = self.load_left_and_top();
282 for (j, line) in buf.chunks_mut(stride).take(4).enumerate() {
283 for (i, pix) in line[..4].iter_mut().enumerate() {
284 let zhd = ((2 * j) as i8) - (i as i8);
285 *pix = if zhd >= 0 {
286 if (zhd & 1) == 0 {
287 (l[j - (i >> 1)] + l[j - (i >> 1) + 1] + 1) >> 1
288 } else {
289 (l[j - (i >> 1) - 1] + 2 * l[j - (i >> 1)] + l[j - (i >> 1) + 1] + 2) >> 2
290 }
291 } else {
292 if zhd == -1 {
293 (l[1] + 2 * l[0] + t[1] + 2) >> 2
294 } else {
295 (t[i - 2] + 2 * t[i - 1] + t[i] + 2) >> 2
296 }
297 } as u8;
298 }
299 }
300 },
301 PredType4x4::VerLeft => {
302 let l = self.load_left();
303 let t = self.load_top();
304 buf[0] = ((2*t[0] + 2*t[1] + l[1] + 2*l[2] + l[3] + 4) >> 3) as u8;
305 let pix = ((t[1] + t[2] + 1) >> 1) as u8;
306 buf[1] = pix;
307 buf[2 * stride] = pix;
308 let pix = ((t[2] + t[3] + 1) >> 1) as u8;
309 buf[2] = pix;
310 buf[1 + 2 * stride] = pix;
311 let pix = ((t[3] + t[4] + 1) >> 1) as u8;
312 buf[3] = pix;
313 buf[2 + 2 * stride] = pix;
314 buf[3 + 2 * stride] = ((t[4] + t[5] + 1) >> 1) as u8;
315 buf[ stride] = ((t[0] + 2*t[1] + t[2] + l[2] + 2*l[3] + l[4] + 4) >> 3) as u8;
316 let pix = ((t[1] + 2*t[2] + t[3] + 2) >> 2) as u8;
317 buf[1 + stride] = pix;
318 buf[ 3 * stride] = pix;
319 let pix = ((t[2] + 2*t[3] + t[4] + 2) >> 2) as u8;
320 buf[2 + stride] = pix;
321 buf[1 + 3 * stride] = pix;
322 let pix = ((t[3] + 2*t[4] + t[5] + 2) >> 2) as u8;
323 buf[3 + stride] = pix;
324 buf[2 + 3 * stride] = pix;
325 buf[3 + 3 * stride] = ((t[4] + 2*t[5] + t[6] + 2) >> 2) as u8;
326 },
327 PredType4x4::HorUp => {
328 let l = self.load_left();
329 let t = self.load_top();
330 buf[0] = ((t[1] + 2*t[2] + t[3] + 2*l[0] + 2*l[1] + 4) >> 3) as u8;
331 buf[1] = ((t[2] + 2*t[3] + t[4] + l[0] + 2*l[1] + l[2] + 4) >> 3) as u8;
332 let pix = ((t[3] + 2*t[4] + t[5] + 2*l[1] + 2*l[2] + 4) >> 3) as u8;
333 buf[2] = pix;
334 buf[ stride] = pix;
335 let pix = ((t[4] + 2*t[5] + t[6] + l[1] + 2*l[2] + l[3] + 4) >> 3) as u8;
336 buf[3] = pix;
337 buf[1 + stride] = pix;
338 let pix = ((t[5] + 2*t[6] + t[7] + 2*l[2] + 2*l[3] + 4) >> 3) as u8;
339 buf[2 + stride] = pix;
340 buf[0 + 2 * stride] = pix;
341 let pix = ((t[6] + 3*t[7] + l[2] + 3*l[3] + 4) >> 3) as u8;
342 buf[3 + stride] = pix;
343 buf[1 + 2 * stride] = pix;
344 let pix = ((l[3] + 2*l[4] + l[5] + 2) >> 2) as u8;
345 buf[3 + 2 * stride] = pix;
346 buf[1 + 3 * stride] = pix;
347 let pix = ((t[6] + t[7] + l[3] + l[4] + 2) >> 2) as u8;
348 buf[0 + 3 * stride] = pix;
349 buf[2 + 2 * stride] = pix;
350 buf[2 + 3 * stride] = ((l[4] + l[5] + 1) >> 1) as u8;
351 buf[3 + 3 * stride] = ((l[4] + 2*l[5] + l[6] + 2) >> 2) as u8;
352 },
353 PredType4x4::DiagDownLeftNoDown => {
354 let l = self.load_left();
355 let t = self.load_top();
356 buf[0] = ((t[0] + t[2] + 2*t[1] + 2 + l[0] + l[2] + 2*l[1] + 2) >> 3) as u8;
357 let pix = ((t[1] + t[3] + 2*t[2] + 2 + l[1] + l[3] + 2*l[2] + 2) >> 3) as u8;
358 buf[1] = pix;
359 buf[0 + stride] = pix;
360 let pix = ((t[2] + t[4] + 2*t[3] + 2 + l[2] + 3*l[3] + 2) >> 3) as u8;
361 buf[2] = pix;
362 buf[1 + stride] = pix;
363 buf[0 + 2 * stride] = pix;
364 let pix = ((t[3] + t[5] + 2*t[4] + 2 + l[3]*4 + 2) >> 3) as u8;
365 buf[3] = pix;
366 buf[2 + stride] = pix;
367 buf[1 + 2 * stride] = pix;
368 buf[0 + 3 * stride] = pix;
369 let pix = ((t[4] + t[6] + 2*t[5] + 2 + l[3]*4 + 2) >> 3) as u8;
370 buf[3 + stride] = pix;
371 buf[2 + 2 * stride] = pix;
372 buf[1 + 3 * stride] = pix;
373 let pix = ((t[5] + t[7] + 2*t[6] + 2 + l[3]*4 + 2) >> 3) as u8;
374 buf[3 + 2 * stride] = pix;
375 buf[2 + 3 * stride] = pix;
376 buf[3 + 3 * stride] = ((t[6] + t[7] + 1 + 2*l[3] + 1) >> 2) as u8;
377 },
378 PredType4x4::HorUpNoDown => {
379 let l = self.load_left();
380 let t = self.load_top();
381 buf[0] = ((t[1] + 2*t[2] + t[3] + 2*l[0] + 2*l[1] + 4) >> 3) as u8;
382 buf[1] = ((t[2] + 2*t[3] + t[4] + l[0] + 2*l[1] + l[2] + 4) >> 3) as u8;
383 let pix = ((t[3] + 2*t[4] + t[5] + 2*l[1] + 2*l[2] + 4) >> 3) as u8;
384 buf[2] = pix;
385 buf[ stride] = pix;
386 let pix = ((t[4] + 2*t[5] + t[6] + l[1] + 2*l[2] + l[3] + 4) >> 3) as u8;
387 buf[3] = pix;
388 buf[1 + stride] = pix;
389 let pix = ((t[5] + 2*t[6] + t[7] + 2*l[2] + 2*l[3] + 4) >> 3) as u8;
390 buf[2 + stride] = pix;
391 buf[ 2 * stride] = pix;
392 let pix = ((t[6] + 3*t[7] + l[2] + 3*l[3] + 4) >> 3) as u8;
393 buf[3 + stride] = pix;
394 buf[1 + 2 * stride] = pix;
395 buf[3 + 2 * stride] = l[3] as u8;
396 buf[1 + 3 * stride] = l[3] as u8;
397 let pix = ((t[6] + t[7] + 2*l[3] + 2) >> 2) as u8;
398 buf[0 + 3 * stride] = pix;
399 buf[2 + 2 * stride] = pix;
400 buf[2 + 3 * stride] = l[3] as u8;
401 buf[3 + 3 * stride] = l[3] as u8;
402 },
403 PredType4x4::VerLeftNoDown => {
404 let l = [u16::from(self.left[0]), u16::from(self.left[1]), u16::from(self.left[2]), u16::from(self.left[3]), u16::from(self.left[3])];
405 let t = self.load_top();
406 buf[0] = ((2*t[0] + 2*t[1] + l[1] + 2*l[2] + l[3] + 4) >> 3) as u8;
407 let pix = ((t[1] + t[2] + 1) >> 1) as u8;
408 buf[1] = pix;
409 buf[ 2 * stride] = pix;
410 let pix = ((t[2] + t[3] + 1) >> 1) as u8;
411 buf[2] = pix;
412 buf[1 + 2 * stride] = pix;
413 let pix = ((t[3] + t[4] + 1) >> 1) as u8;
414 buf[3] = pix;
415 buf[2 + 2 * stride] = pix;
416 buf[3 + 2 * stride] = ((t[4] + t[5] + 1) >> 1) as u8;
417 buf[ stride] = ((t[0] + 2*t[1] + t[2] + l[2] + 2*l[3] + l[4] + 4) >> 3) as u8;
418 let pix = ((t[1] + 2*t[2] + t[3] + 2) >> 2) as u8;
419 buf[1 + stride] = pix;
420 buf[ 3 * stride] = pix;
421 let pix = ((t[2] + 2*t[3] + t[4] + 2) >> 2) as u8;
422 buf[2 + stride] = pix;
423 buf[1 + 3 * stride] = pix;
424 let pix = ((t[3] + 2*t[4] + t[5] + 2) >> 2) as u8;
425 buf[3 + stride] = pix;
426 buf[2 + 3 * stride] = pix;
427 buf[3 + 3 * stride] = ((t[4] + 2*t[5] + t[6] + 2) >> 2) as u8;
428 },
429 }
430 }
431}
432
433pub struct BlockIntra4Pred {
434 pub ipred_y: Intra4Pred,
435 pub ipred_u: Intra4Pred,
436 pub ipred_v: Intra4Pred,
437 pub top_y: [u8; 21],
438 pub top_u: [u8; 13],
439 pub top_v: [u8; 13],
440 pub left_y: [u8; 16],
441 pub left_u: [u8; 8],
442 pub left_v: [u8; 8],
443 pub has_l: bool,
444}
445
446impl BlockIntra4Pred {
447 pub fn new(src_y: &IntraPred16x16, src_u: &IntraPred16x16, src_v: &IntraPred16x16, tr_y: [u8; 4], tr_u: [u8; 4], tr_v: [u8; 4], has_l: bool) -> Self {
448 let mut top_y = [0; 21];
449 top_y[..17].copy_from_slice(&src_y.top);
450 top_y[17..].copy_from_slice(&tr_y);
451 let mut top_u = [0; 13];
452 top_u[..9].copy_from_slice(&src_u.top[..9]);
453 top_u[9..].copy_from_slice(&tr_u);
454 let mut top_v = [0; 13];
455 top_v[..9].copy_from_slice(&src_v.top[..9]);
456 top_v[9..].copy_from_slice(&tr_v);
457 let mut left_y = [0; 16];
458 left_y.copy_from_slice(&src_y.left[1..]);
459 let mut left_u = [0; 8];
460 left_u.copy_from_slice(&src_u.left[1..9]);
461 let mut left_v = [0; 8];
462 left_v.copy_from_slice(&src_v.left[1..9]);
463 Self {
464 ipred_y: Intra4Pred::new(),
465 ipred_u: Intra4Pred::new(),
466 ipred_v: Intra4Pred::new(),
467 top_y, top_u, top_v, left_y, left_u, left_v,
468 has_l,
469 }
470 }
471 pub fn pred_block(&mut self, dst: &mut RefMBData, x: usize, y: usize, mode: PredType4x4) {
472 let do_chroma = ((x & 1) == 0) && ((y & 1) == 0);
473 if x == 0 {
474 self.ipred_y.tl = if y == 0 { self.top_y[0] } else { self.left_y[y * 4 - 1] };
475 if y != 3 {
476 self.ipred_y.left.copy_from_slice(&self.left_y[y * 4..][..8]);
477 } else {
478 self.ipred_y.left[..4].copy_from_slice(&self.left_y[12..]);
479 }
480 if y == 0 {
481 self.ipred_u.tl = self.top_u[0];
482 self.ipred_v.tl = self.top_v[0];
483 self.ipred_u.left.copy_from_slice(&self.left_u);
484 self.ipred_v.left.copy_from_slice(&self.left_v);
485 } else if y == 2 {
486 self.ipred_u.tl = self.left_u[3];
487 self.ipred_v.tl = self.left_v[3];
488 self.ipred_u.left[..4].copy_from_slice(&self.left_u[4..]);
489 self.ipred_v.left[..4].copy_from_slice(&self.left_v[4..]);
490 }
491 }
492 self.ipred_y.top.copy_from_slice(&self.top_y[x * 4 + 1..][..8]);
493 if do_chroma {
494 if x == 0 {
495 self.ipred_u.top.copy_from_slice(&self.top_u[1..9]);
496 self.ipred_v.top.copy_from_slice(&self.top_v[1..9]);
497 } else if x == 2 {
498 self.ipred_u.top.copy_from_slice(&self.top_u[5..]);
499 self.ipred_v.top.copy_from_slice(&self.top_v[5..]);
500 }
501 }
502
503 self.ipred_y.apply(mode, &mut dst.y[x * 4 + y * 4 * 16..], 16);
504 if do_chroma {
505 let has_ld = if (x == 0) && (y == 0) { self.has_l } else { false };
506 let off = x * 2 + y * 2 * 8;
507 let cmode = match mode {
508 PredType4x4::DiagDownLeft if !has_ld => PredType4x4::DiagDownLeftNoDown,
509 PredType4x4::VerLeft if !has_ld => PredType4x4::VerLeftNoDown,
510 PredType4x4::HorUp if !has_ld => PredType4x4::HorUpNoDown,
511 _ => mode,
512 };
513 self.ipred_u.apply(cmode, &mut dst.u[off..], 8);
514 self.ipred_v.apply(cmode, &mut dst.v[off..], 8);
515 }
516 }
517 pub fn update_from(&mut self, src: &RefMBData, x: usize, y: usize) {
518 let do_chroma = ((x & 1) == 0) && ((y & 1) == 0);
519 let y_off = x * 4 + y * 4 * 16;
520 let c_off = x * 2 + y * 2 * 8;
521
522 if x != 3 {
523 self.ipred_y.tl = self.ipred_y.top[3];
524 for (left, src) in self.ipred_y.left[..4].iter_mut().zip(src.y[y_off + 3..].chunks(16)) {
525 *left = src[0];
526 }
527 }
528 if do_chroma && x != 2 {
529 self.ipred_u.tl = self.ipred_u.top[3];
530 self.ipred_v.tl = self.ipred_v.top[3];
531 for (left, src) in self.ipred_u.left[..4].iter_mut().zip(src.u[c_off + 3..].chunks(8)) {
532 *left = src[0];
533 }
534 for (left, src) in self.ipred_v.left[..4].iter_mut().zip(src.v[c_off + 3..].chunks(8)) {
535 *left = src[0];
536 }
537 }
538 if x == 0 {
539 self.top_y[0] = self.left_y[x * 4 + 3];
540 if y == 0 {
541 self.top_u[0] = self.left_u[3];
542 self.top_v[0] = self.left_v[3];
543 }
544 }
545 self.top_y[x * 4 + 1..][..4].copy_from_slice(&src.y[y_off + 3 * 16..][..4]);
546 if x == 3 {
547 let (head, tail) = self.top_y.split_at_mut(17);
548 for el in tail.iter_mut() {
549 *el = head[16];
550 }
551 }
552 if do_chroma && y != 2 {
553 self.top_u[x * 2 + 1..][..4].copy_from_slice(&src.u[c_off + 3 * 8..][..4]);
554 self.top_v[x * 2 + 1..][..4].copy_from_slice(&src.v[c_off + 3 * 8..][..4]);
555 if x == 2 {
556 for i in 9..13 {
557 self.top_u[i] = self.top_u[8];
558 self.top_v[i] = self.top_v[8];
559 }
560 }
561 }
562 }
563}