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