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