Skip to main content

aom_decode/
chroma.rs

1/// A pixel in YUV (YCbCr, `YCgCo`, etc.) planar color space
2#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, Hash)]
3pub struct YUV<T> {
4    /// Luma
5    pub y: T,
6    /// First chroma channel (Cb)
7    pub u: T,
8    /// Second chroma channel (Cr)
9    pub v: T,
10}
11
12/// Iterator that combines equal-sized planes of Y, U, V into YUV pixels
13pub fn yuv_444<'a, T: Copy + 'a, YRowsIter, URowsIter, VRowsIter>(y: YRowsIter, u: URowsIter, v: VRowsIter) -> impl Iterator<Item = YUV<T>> + 'a
14where
15    YRowsIter: Iterator<Item = &'a [T]> + 'a,
16    URowsIter: Iterator<Item = &'a [T]> + 'a,
17    VRowsIter: Iterator<Item = &'a [T]> + 'a,
18{
19    y.zip(u.zip(v))
20        .flat_map(|(y,(u,v))| {
21            y.iter().copied().zip(u.iter().copied().zip(v.iter().copied()))
22            .map(|(y,(u,v))| YUV{y,u,v})
23        })
24}
25
26/// Iterator that combines planes of Y, U, V into YUV pixels, where U and V have half width
27///
28/// Uses nearest-neighbor scaling.
29pub fn yuv_422<'a, T: Copy + 'a, YRowsIter, URowsIter, VRowsIter>(y: YRowsIter, u: URowsIter, v: VRowsIter) -> impl Iterator<Item = YUV<T>> + 'a
30where
31    YRowsIter: Iterator<Item = &'a [T]> + 'a,
32    URowsIter: Iterator<Item = &'a [T]> + 'a,
33    VRowsIter: Iterator<Item = &'a [T]> + 'a,
34{
35    y.zip(u.zip(v))
36        .flat_map(|(y,(u,v))| {
37            let u = u.iter().copied().flat_map(|u_px| std::iter::repeat_n(u_px, 2));
38            let v = v.iter().copied().flat_map(|v_px| std::iter::repeat_n(v_px, 2));
39            y.iter().copied().zip(u.zip(v))
40            .map(|(y,(u,v))| YUV{y,u,v})
41        })
42}
43
44/// Iterator that combines planes of Y, U, V into YUV pixels, where U and V have half width and half height
45///
46/// Uses nearest-neighbor scaling.
47pub fn yuv_420<'a, T: Copy + 'a, YRowsIter, URowsIter, VRowsIter>(y: YRowsIter, u: URowsIter, v: VRowsIter) -> impl Iterator<Item = YUV<T>> + 'a
48where
49    YRowsIter: Iterator<Item = &'a [T]> + 'a,
50    URowsIter: Iterator<Item = &'a [T]> + 'a,
51    VRowsIter: Iterator<Item = &'a [T]> + 'a,
52{
53    let u = u.flat_map(|u_row| std::iter::repeat_n(u_row, 2));
54    let v = v.flat_map(|v_row| std::iter::repeat_n(v_row, 2));
55    y.zip(u.zip(v))
56    .flat_map(|(y,(u,v))| {
57        let u = u.iter().copied().flat_map(|u_px| std::iter::repeat_n(u_px, 2));
58        let v = v.iter().copied().flat_map(|v_px| std::iter::repeat_n(v_px, 2));
59        y.iter().copied().zip(u.zip(v))
60        .map(|(y,(u,v))| YUV{y,u,v})
61    })
62}