zune_jpeg/color_convert/
scalar.rs
1use core::convert::TryInto;
10
11#[inline]
13#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss, dead_code)]
14fn clamp(a: i16) -> u8 {
15 a.clamp(0, 255) as u8
16}
17
18pub fn ycbcr_to_rgba_inner_16_scalar<const BGRA: bool>(
26 y: &[i16; 16], cb: &[i16; 16], cr: &[i16; 16], output: &mut [u8], pos: &mut usize
27) {
28 let (_, output_position) = output.split_at_mut(*pos);
29
30 let opt: &mut [u8; 64] = output_position
32 .get_mut(0..64)
33 .expect("Slice to small cannot write")
34 .try_into()
35 .unwrap();
36 for ((y, (cb, cr)), out) in y
37 .iter()
38 .zip(cb.iter().zip(cr.iter()))
39 .zip(opt.chunks_exact_mut(4))
40 {
41 let cr = cr - 128;
42 let cb = cb - 128;
43
44 let r = y + ((45_i16.wrapping_mul(cr)) >> 5);
45 let g = y - ((11_i16.wrapping_mul(cb) + 23_i16.wrapping_mul(cr)) >> 5);
46 let b = y + ((113_i16.wrapping_mul(cb)) >> 6);
47
48 if BGRA {
49 out[0] = clamp(b);
50 out[1] = clamp(g);
51 out[2] = clamp(r);
52 out[3] = 255;
53 } else {
54 out[0] = clamp(r);
55 out[1] = clamp(g);
56 out[2] = clamp(b);
57 out[3] = 255;
58 }
59 }
60 *pos += 64;
61}
62
63pub fn ycbcr_to_rgb_inner_16_scalar<const BGRA: bool>(
69 y: &[i16; 16], cb: &[i16; 16], cr: &[i16; 16], output: &mut [u8], pos: &mut usize
70) {
71 let (_, output_position) = output.split_at_mut(*pos);
72
73 let opt: &mut [u8; 48] = output_position
75 .get_mut(0..48)
76 .expect("Slice to small cannot write")
77 .try_into()
78 .unwrap();
79
80 for ((y, (cb, cr)), out) in y
81 .iter()
82 .zip(cb.iter().zip(cr.iter()))
83 .zip(opt.chunks_exact_mut(3))
84 {
85 let cr = cr - 128;
86 let cb = cb - 128;
87
88 let r = y + ((45_i16.wrapping_mul(cr)) >> 5);
89 let g = y - ((11_i16.wrapping_mul(cb) + 23_i16.wrapping_mul(cr)) >> 5);
90 let b = y + ((113_i16.wrapping_mul(cb)) >> 6);
91
92 if BGRA {
93 out[0] = clamp(b);
94 out[1] = clamp(g);
95 out[2] = clamp(r);
96 } else {
97 out[0] = clamp(r);
98 out[1] = clamp(g);
99 out[2] = clamp(b);
100 }
101 }
102
103 *pos += 48;
105}
106
107pub fn ycbcr_to_grayscale(y: &[i16], width: usize, padded_width: usize, output: &mut [u8]) {
108 for (y_in, out) in y
109 .chunks_exact(padded_width)
110 .zip(output.chunks_exact_mut(width))
111 {
112 for (y, out) in y_in.iter().zip(out.iter_mut()) {
113 *out = *y as u8;
114 }
115 }
116}