av1_grain/
util.rs

1#[cfg(feature = "diff")]
2use std::{borrow::Cow, mem::size_of};
3
4#[cfg(feature = "diff")]
5use v_frame::{
6    frame::Frame,
7    prelude::{CastFromPrimitive, ChromaSampling, Pixel},
8};
9
10#[cfg(feature = "diff")]
11pub fn frame_into_u8<T: Pixel>(frame: &Frame<T>, bit_depth: usize) -> Cow<'_, Frame<u8>> {
12    if size_of::<T>() == 1 {
13        assert_eq!(bit_depth, 8);
14        // SAFETY: We know from the size check that this must be a `Frame<u8>`
15        Cow::Borrowed(unsafe { &*(frame as *const Frame<T>).cast::<Frame<u8>>() })
16    } else if size_of::<T>() == 2 {
17        assert!(bit_depth > 8 && bit_depth <= 16);
18        let mut u8_frame: Frame<u8> = Frame::new_with_padding(
19            frame.planes[0].cfg.width,
20            frame.planes[0].cfg.height,
21            match frame.planes[1].cfg.xdec + frame.planes[1].cfg.ydec {
22                0 => ChromaSampling::Cs444,
23                1 => ChromaSampling::Cs422,
24                2 => ChromaSampling::Cs420,
25                _ => unreachable!(),
26            },
27            frame.planes[0].cfg.xpad,
28        );
29        for i in 0..3 {
30            let out_plane = &mut u8_frame.planes[i];
31            for (i, o) in frame.planes[i]
32                .data_origin()
33                .iter()
34                .zip(out_plane.data_origin_mut().iter_mut())
35            {
36                *o = (u16::cast_from(*i) >> (bit_depth - 8usize)) as u8;
37            }
38        }
39        Cow::Owned(u8_frame)
40    } else {
41        unimplemented!("Bit depths greater than 16 are not currently supported");
42    }
43}