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 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}