1use crate::enc::helpers::{bt601_cb, bt601_cr, bt601_y};
5use crate::pixel_utils::clamp_u8;
6
7#[must_use]
12pub fn encode_uyvy(bgra: &[u8], w: i32, h: i32) -> Vec<u8> {
13 let wu = w as usize;
14 let hu = h as usize;
15 let n = wu * hu;
16 let pairs_per_row = wu.div_ceil(2);
18 let total_pairs = pairs_per_row * hu;
19 let mut out = vec![0u8; total_pairs * 4];
20
21 let mut px_i = 0;
22 let mut o_i = 0;
23 while px_i < n {
24 let px = px_i * 4;
25 let r0 = i32::from(bgra[px + 2]);
26 let g0 = i32::from(bgra[px + 1]);
27 let b0 = i32::from(bgra[px]);
28 let y0 = clamp_u8(bt601_y(r0, g0, b0));
29 let cb0 = bt601_cb(r0, g0, b0);
30 let cr0 = bt601_cr(r0, g0, b0);
31
32 if px_i + 1 < n {
33 let px2 = (px_i + 1) * 4;
35 let r1 = i32::from(bgra[px2 + 2]);
36 let g1 = i32::from(bgra[px2 + 1]);
37 let b1 = i32::from(bgra[px2]);
38 let y1 = clamp_u8(bt601_y(r1, g1, b1));
39 let cb1 = bt601_cb(r1, g1, b1);
40 let cr1 = bt601_cr(r1, g1, b1);
41
42 let cb_avg = clamp_u8(cb0.midpoint(cb1));
43 let cr_avg = clamp_u8(cr0.midpoint(cr1));
44
45 out[o_i] = cb_avg;
46 out[o_i + 1] = y0;
47 out[o_i + 2] = cr_avg;
48 out[o_i + 3] = y1;
49 } else {
50 out[o_i] = clamp_u8(cb0);
52 out[o_i + 1] = y0;
53 out[o_i + 2] = clamp_u8(cr0);
54 out[o_i + 3] = 0;
55 }
56
57 px_i += 2;
58 o_i += 4;
59 }
60
61 out
62}