1 use super::super::types::{PredType8x8, PredType4x4};
5 pub struct 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) {
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() {
26 for (&left, line) in self.left[1..].iter().zip(dst.chunks_mut(stride)) {
27 for dst in line[..16].iter_mut() {
33 for line in dst.chunks_mut(stride).take(16) {
34 line[..16].copy_from_slice(&self.top[1..]);
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);
50 for line in dst.chunks_mut(stride).take(16) {
52 for el in line[..16].iter_mut() {
53 *el = (oval >> 5).max(0).min(255) as u8;
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() {
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() {
75 PredType8x8::DC128 => {
76 for line in dst.chunks_mut(stride).take(16) {
77 for dst in line[..16].iter_mut() {
84 pub fn apply8(&self, mode: PredType8x8, dst: &mut [u8], stride: usize) {
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() {
97 for (&left, line) in self.left[1..9].iter().zip(dst.chunks_mut(stride)) {
98 for dst in line[..8].iter_mut() {
103 PredType8x8::Ver => {
104 for line in dst.chunks_mut(stride).take(8) {
105 line[..8].copy_from_slice(&self.top[1..9]);
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() {
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() {
124 PredType8x8::DC128 => {
125 for line in dst.chunks_mut(stride).take(8) {
126 for dst in line[..8].iter_mut() {
136 pub struct 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);
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);
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);
166 for (dst, &src) in top[1..].iter_mut().zip(self.top.iter()) {
167 *dst = u16::from(src);
171 #[allow(clippy::many_single_char_names)]
172 pub fn apply(&self, ptype: PredType4x4, buf: &mut [u8], stride: usize) {
175 let dc_l = self.left[..4].iter().fold(0u32, |acc, &x| acc + u32::from(x));
176 let dc_t = self.top [..4].iter().fold(0u32, |acc, &x| acc + u32::from(x));
177 let dc = ((dc_t + dc_l + 4) >> 3) as u8;
178 for line in buf.chunks_mut(stride).take(4) {
179 for el in line[..4].iter_mut() {
184 PredType4x4::LeftDC => {
185 let dc_l = self.left[..4].iter().fold(0u32, |acc, &x| acc + u32::from(x));
186 let dc = ((dc_l + 2) >> 2) as u8;
187 for line in buf.chunks_mut(stride).take(4) {
188 for el in line[..4].iter_mut() {
193 PredType4x4::TopDC => {
194 let dc_t = self.top [..4].iter().fold(0u32, |acc, &x| acc + u32::from(x));
195 let dc = ((dc_t + 2) >> 2) as u8;
196 for line in buf.chunks_mut(stride).take(4) {
197 for el in line[..4].iter_mut() {
202 PredType4x4::DC128 => {
203 for line in buf.chunks_mut(stride).take(4) {
204 for el in line[..4].iter_mut() {
209 PredType4x4::Ver => {
210 for line in buf.chunks_mut(stride).take(4) {
211 line[..4].copy_from_slice(&self.top[..4]);
214 PredType4x4::Hor => {
215 for (&left, line) in self.left[..4].iter().zip(buf.chunks_mut(stride)) {
216 for dst in line[..4].iter_mut() {
221 PredType4x4::DiagDownLeft => {
222 let l = self.load_left();
223 let t = self.load_top();
224 buf[0] = ((t[0] + t[2] + 2*t[1] + 2 + l[0] + l[2] + 2*l[1] + 2) >> 3) as u8;
225 let pix = ((t[1] + t[3] + 2*t[2] + 2 + l[1] + l[3] + 2*l[2] + 2) >> 3) as u8;
228 let pix = ((t[2] + t[4] + 2*t[3] + 2 + l[2] + l[4] + 2*l[3] + 2) >> 3) as u8;
230 buf[1 + stride] = pix;
231 buf[2 * stride] = pix;
232 let pix = ((t[3] + t[5] + 2*t[4] + 2 + l[3] + l[5] + 2*l[4] + 2) >> 3) as u8;
234 buf[2 + stride] = pix;
235 buf[1 + 2 * stride] = pix;
236 buf[ 3 * stride] = pix;
237 let pix = ((t[4] + t[6] + 2*t[5] + 2 + l[4] + l[6] + 2*l[5] + 2) >> 3) as u8;
238 buf[3 + stride] = pix;
239 buf[2 + 2 * stride] = pix;
240 buf[1 + 3 * stride] = pix;
241 let pix = ((t[5] + t[7] + 2*t[6] + 2 + l[5] + l[7] + 2*l[6] + 2) >> 3) as u8;
242 buf[3 + 2 * stride] = pix;
243 buf[2 + 3 * stride] = pix;
244 buf[3 + 3 * stride] = ((t[6] + t[7] + 1 + l[6] + l[7] + 1) >> 2) as u8;
246 PredType4x4::DiagDownRight => {
247 let (l, t) = self.load_left_and_top();
248 for (j, line) in buf.chunks_mut(stride).take(4).enumerate() {
250 line[i] = ((l[j - i - 1] + 2 * l[j - i] + l[j - i + 1] + 2) >> 2) as u8;
252 line[j] = ((l[1] + 2 * l[0] + t[1] + 2) >> 2) as u8;
253 for i in (j + 1)..4 {
254 line[i] = ((t[i - j - 1] + 2 * t[i - j] + t[i - j + 1] + 2) >> 2) as u8;
258 PredType4x4::VerRight => {
259 let (l, t) = self.load_left_and_top();
260 for (j, line) in buf.chunks_mut(stride).take(4).enumerate() {
261 for (i, pix) in line[..4].iter_mut().enumerate() {
262 let zvr = ((2 * i) as i8) - (j as i8);
265 (t[i - (j >> 1)] + t[i - (j >> 1) + 1] + 1) >> 1
267 (t[i - (j >> 1) - 1] + 2 * t[i - (j >> 1)] + t[i - (j >> 1) + 1] + 2) >> 2
271 (l[1] + 2 * l[0] + t[1] + 2) >> 2
273 (l[j] + 2 * l[j - 1] + l[j - 2] + 2) >> 2
279 PredType4x4::HorDown => {
280 let (l, t) = self.load_left_and_top();
281 for (j, line) in buf.chunks_mut(stride).take(4).enumerate() {
282 for (i, pix) in line[..4].iter_mut().enumerate() {
283 let zhd = ((2 * j) as i8) - (i as i8);
286 (l[j - (i >> 1)] + l[j - (i >> 1) + 1] + 1) >> 1
288 (l[j - (i >> 1) - 1] + 2 * l[j - (i >> 1)] + l[j - (i >> 1) + 1] + 2) >> 2
292 (l[1] + 2 * l[0] + t[1] + 2) >> 2
294 (t[i - 2] + 2 * t[i - 1] + t[i] + 2) >> 2
300 PredType4x4::VerLeft => {
301 let l = self.load_left();
302 let t = self.load_top();
303 buf[0] = ((2*t[0] + 2*t[1] + l[1] + 2*l[2] + l[3] + 4) >> 3) as u8;
304 let pix = ((t[1] + t[2] + 1) >> 1) as u8;
306 buf[2 * stride] = pix;
307 let pix = ((t[2] + t[3] + 1) >> 1) as u8;
309 buf[1 + 2 * stride] = pix;
310 let pix = ((t[3] + t[4] + 1) >> 1) as u8;
312 buf[2 + 2 * stride] = pix;
313 buf[3 + 2 * stride] = ((t[4] + t[5] + 1) >> 1) as u8;
314 buf[ stride] = ((t[0] + 2*t[1] + t[2] + l[2] + 2*l[3] + l[4] + 4) >> 3) as u8;
315 let pix = ((t[1] + 2*t[2] + t[3] + 2) >> 2) as u8;
316 buf[1 + stride] = pix;
317 buf[ 3 * stride] = pix;
318 let pix = ((t[2] + 2*t[3] + t[4] + 2) >> 2) as u8;
319 buf[2 + stride] = pix;
320 buf[1 + 3 * stride] = pix;
321 let pix = ((t[3] + 2*t[4] + t[5] + 2) >> 2) as u8;
322 buf[3 + stride] = pix;
323 buf[2 + 3 * stride] = pix;
324 buf[3 + 3 * stride] = ((t[4] + 2*t[5] + t[6] + 2) >> 2) as u8;
326 PredType4x4::HorUp => {
327 let l = self.load_left();
328 let t = self.load_top();
329 buf[0] = ((t[1] + 2*t[2] + t[3] + 2*l[0] + 2*l[1] + 4) >> 3) as u8;
330 buf[1] = ((t[2] + 2*t[3] + t[4] + l[0] + 2*l[1] + l[2] + 4) >> 3) as u8;
331 let pix = ((t[3] + 2*t[4] + t[5] + 2*l[1] + 2*l[2] + 4) >> 3) as u8;
334 let pix = ((t[4] + 2*t[5] + t[6] + l[1] + 2*l[2] + l[3] + 4) >> 3) as u8;
336 buf[1 + stride] = pix;
337 let pix = ((t[5] + 2*t[6] + t[7] + 2*l[2] + 2*l[3] + 4) >> 3) as u8;
338 buf[2 + stride] = pix;
339 buf[0 + 2 * stride] = pix;
340 let pix = ((t[6] + 3*t[7] + l[2] + 3*l[3] + 4) >> 3) as u8;
341 buf[3 + stride] = pix;
342 buf[1 + 2 * stride] = pix;
343 let pix = ((l[3] + 2*l[4] + l[5] + 2) >> 2) as u8;
344 buf[3 + 2 * stride] = pix;
345 buf[1 + 3 * stride] = pix;
346 let pix = ((t[6] + t[7] + l[3] + l[4] + 2) >> 2) as u8;
347 buf[0 + 3 * stride] = pix;
348 buf[2 + 2 * stride] = pix;
349 buf[2 + 3 * stride] = ((l[4] + l[5] + 1) >> 1) as u8;
350 buf[3 + 3 * stride] = ((l[4] + 2*l[5] + l[6] + 2) >> 2) as u8;
352 PredType4x4::DiagDownLeftNoDown => {
353 let l = self.load_left();
354 let t = self.load_top();
355 buf[0] = ((t[0] + t[2] + 2*t[1] + 2 + l[0] + l[2] + 2*l[1] + 2) >> 3) as u8;
356 let pix = ((t[1] + t[3] + 2*t[2] + 2 + l[1] + l[3] + 2*l[2] + 2) >> 3) as u8;
358 buf[0 + stride] = pix;
359 let pix = ((t[2] + t[4] + 2*t[3] + 2 + l[2] + 3*l[3] + 2) >> 3) as u8;
361 buf[1 + stride] = pix;
362 buf[0 + 2 * stride] = pix;
363 let pix = ((t[3] + t[5] + 2*t[4] + 2 + l[3]*4 + 2) >> 3) as u8;
365 buf[2 + stride] = pix;
366 buf[1 + 2 * stride] = pix;
367 buf[0 + 3 * stride] = pix;
368 let pix = ((t[4] + t[6] + 2*t[5] + 2 + l[3]*4 + 2) >> 3) as u8;
369 buf[3 + stride] = pix;
370 buf[2 + 2 * stride] = pix;
371 buf[1 + 3 * stride] = pix;
372 let pix = ((t[5] + t[7] + 2*t[6] + 2 + l[3]*4 + 2) >> 3) as u8;
373 buf[3 + 2 * stride] = pix;
374 buf[2 + 3 * stride] = pix;
375 buf[3 + 3 * stride] = ((t[6] + t[7] + 1 + 2*l[3] + 1) >> 2) as u8;
377 PredType4x4::HorUpNoDown => {
378 let l = self.load_left();
379 let t = self.load_top();
380 buf[0] = ((t[1] + 2*t[2] + t[3] + 2*l[0] + 2*l[1] + 4) >> 3) as u8;
381 buf[1] = ((t[2] + 2*t[3] + t[4] + l[0] + 2*l[1] + l[2] + 4) >> 3) as u8;
382 let pix = ((t[3] + 2*t[4] + t[5] + 2*l[1] + 2*l[2] + 4) >> 3) as u8;
385 let pix = ((t[4] + 2*t[5] + t[6] + l[1] + 2*l[2] + l[3] + 4) >> 3) as u8;
387 buf[1 + stride] = pix;
388 let pix = ((t[5] + 2*t[6] + t[7] + 2*l[2] + 2*l[3] + 4) >> 3) as u8;
389 buf[2 + stride] = pix;
390 buf[ 2 * stride] = pix;
391 let pix = ((t[6] + 3*t[7] + l[2] + 3*l[3] + 4) >> 3) as u8;
392 buf[3 + stride] = pix;
393 buf[1 + 2 * stride] = pix;
394 buf[3 + 2 * stride] = l[3] as u8;
395 buf[1 + 3 * stride] = l[3] as u8;
396 let pix = ((t[6] + t[7] + 2*l[3] + 2) >> 2) as u8;
397 buf[0 + 3 * stride] = pix;
398 buf[2 + 2 * stride] = pix;
399 buf[2 + 3 * stride] = l[3] as u8;
400 buf[3 + 3 * stride] = l[3] as u8;
402 PredType4x4::VerLeftNoDown => {
403 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])];
404 let t = self.load_top();
405 buf[0] = ((2*t[0] + 2*t[1] + l[1] + 2*l[2] + l[3] + 4) >> 3) as u8;
406 let pix = ((t[1] + t[2] + 1) >> 1) as u8;
408 buf[ 2 * stride] = pix;
409 let pix = ((t[2] + t[3] + 1) >> 1) as u8;
411 buf[1 + 2 * stride] = pix;
412 let pix = ((t[3] + t[4] + 1) >> 1) as u8;
414 buf[2 + 2 * stride] = pix;
415 buf[3 + 2 * stride] = ((t[4] + t[5] + 1) >> 1) as u8;
416 buf[ stride] = ((t[0] + 2*t[1] + t[2] + l[2] + 2*l[3] + l[4] + 4) >> 3) as u8;
417 let pix = ((t[1] + 2*t[2] + t[3] + 2) >> 2) as u8;
418 buf[1 + stride] = pix;
419 buf[ 3 * stride] = pix;
420 let pix = ((t[2] + 2*t[3] + t[4] + 2) >> 2) as u8;
421 buf[2 + stride] = pix;
422 buf[1 + 3 * stride] = pix;
423 let pix = ((t[3] + 2*t[4] + t[5] + 2) >> 2) as u8;
424 buf[3 + stride] = pix;
425 buf[2 + 3 * stride] = pix;
426 buf[3 + 3 * stride] = ((t[4] + 2*t[5] + t[6] + 2) >> 2) as u8;
432 pub struct BlockIntra4Pred {
433 pub ipred_y: Intra4Pred,
434 pub ipred_u: Intra4Pred,
435 pub ipred_v: Intra4Pred,
439 pub left_y: [u8; 16],
445 impl BlockIntra4Pred {
446 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 {
447 let mut top_y = [0; 21];
448 top_y[..17].copy_from_slice(&src_y.top);
449 top_y[17..].copy_from_slice(&tr_y);
450 let mut top_u = [0; 13];
451 top_u[..9].copy_from_slice(&src_u.top[..9]);
452 top_u[9..].copy_from_slice(&tr_u);
453 let mut top_v = [0; 13];
454 top_v[..9].copy_from_slice(&src_v.top[..9]);
455 top_v[9..].copy_from_slice(&tr_v);
456 let mut left_y = [0; 16];
457 left_y.copy_from_slice(&src_y.left[1..]);
458 let mut left_u = [0; 8];
459 left_u.copy_from_slice(&src_u.left[1..9]);
460 let mut left_v = [0; 8];
461 left_v.copy_from_slice(&src_v.left[1..9]);
463 ipred_y: Intra4Pred::new(),
464 ipred_u: Intra4Pred::new(),
465 ipred_v: Intra4Pred::new(),
466 top_y, top_u, top_v, left_y, left_u, left_v,
470 pub fn pred_block(&mut self, dst: &mut RefMBData, x: usize, y: usize, mode: PredType4x4) {
471 let do_chroma = ((x & 1) == 0) && ((y & 1) == 0);
473 self.ipred_y.tl = if y == 0 { self.top_y[0] } else { self.left_y[y * 4 - 1] };
475 self.ipred_y.left.copy_from_slice(&self.left_y[y * 4..][..8]);
477 self.ipred_y.left[..4].copy_from_slice(&self.left_y[12..]);
480 self.ipred_u.tl = self.top_u[0];
481 self.ipred_v.tl = self.top_v[0];
482 self.ipred_u.left.copy_from_slice(&self.left_u);
483 self.ipred_v.left.copy_from_slice(&self.left_v);
485 self.ipred_u.tl = self.left_u[3];
486 self.ipred_v.tl = self.left_v[3];
487 self.ipred_u.left[..4].copy_from_slice(&self.left_u[4..]);
488 self.ipred_v.left[..4].copy_from_slice(&self.left_v[4..]);
491 self.ipred_y.top.copy_from_slice(&self.top_y[x * 4 + 1..][..8]);
494 self.ipred_u.top.copy_from_slice(&self.top_u[1..9]);
495 self.ipred_v.top.copy_from_slice(&self.top_v[1..9]);
497 self.ipred_u.top.copy_from_slice(&self.top_u[5..]);
498 self.ipred_v.top.copy_from_slice(&self.top_v[5..]);
502 self.ipred_y.apply(mode, &mut dst.y[x * 4 + y * 4 * 16..], 16);
504 let has_ld = if (x == 0) && (y == 0) { self.has_l } else { false };
505 let off = x * 2 + y * 2 * 8;
506 let cmode = match mode {
507 PredType4x4::DiagDownLeft if !has_ld => PredType4x4::DiagDownLeftNoDown,
508 PredType4x4::VerLeft if !has_ld => PredType4x4::VerLeftNoDown,
509 PredType4x4::HorUp if !has_ld => PredType4x4::HorUpNoDown,
512 self.ipred_u.apply(cmode, &mut dst.u[off..], 8);
513 self.ipred_v.apply(cmode, &mut dst.v[off..], 8);
516 pub fn update_from(&mut self, src: &RefMBData, x: usize, y: usize) {
517 let do_chroma = ((x & 1) == 0) && ((y & 1) == 0);
518 let y_off = x * 4 + y * 4 * 16;
519 let c_off = x * 2 + y * 2 * 8;
522 self.ipred_y.tl = self.ipred_y.top[3];
523 for (left, src) in self.ipred_y.left[..4].iter_mut().zip(src.y[y_off + 3..].chunks(16)) {
527 if do_chroma && x != 2 {
528 self.ipred_u.tl = self.ipred_u.top[3];
529 self.ipred_v.tl = self.ipred_v.top[3];
530 for (left, src) in self.ipred_u.left[..4].iter_mut().zip(src.u[c_off + 3..].chunks(8)) {
533 for (left, src) in self.ipred_v.left[..4].iter_mut().zip(src.v[c_off + 3..].chunks(8)) {
538 self.top_y[0] = self.left_y[x * 4 + 3];
540 self.top_u[0] = self.left_u[3];
541 self.top_v[0] = self.left_v[3];
544 self.top_y[x * 4 + 1..][..4].copy_from_slice(&src.y[y_off + 3 * 16..][..4]);
546 let (head, tail) = self.top_y.split_at_mut(17);
547 for el in tail.iter_mut() {
551 if do_chroma && y != 2 {
552 self.top_u[x * 2 + 1..][..4].copy_from_slice(&src.u[c_off + 3 * 8..][..4]);
553 self.top_v[x * 2 + 1..][..4].copy_from_slice(&src.v[c_off + 3 * 8..][..4]);
556 self.top_u[i] = self.top_u[8];
557 self.top_v[i] = self.top_v[8];