From fdb3de89a9fd434642790d150242e9520c8304e6 Mon Sep 17 00:00:00 2001 From: Oliver Atkinson Date: Thu, 29 Jun 2023 20:23:35 -0600 Subject: [PATCH] choose your screen type --- .gitignore | 1 + input => rgb.png | Bin 563 -> 599 bytes src/main.rs | 8 +++-- src/out.rs | 74 +++++++++++++++++++++++++++++++++++++++++++++++ src/test.rs | 38 ------------------------ 5 files changed, 80 insertions(+), 41 deletions(-) rename input => rgb.png (67%) create mode 100644 src/out.rs delete mode 100644 src/test.rs diff --git a/.gitignore b/.gitignore index 81cf465..1e11a99 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target /.vscode +*.png diff --git a/input b/rgb.png similarity index 67% rename from input rename to rgb.png index 9e3eb681d866a4152aaa221f4cd86ddea477645e..34941ec9d06aa316eb454e9649a7a0437e554077 100644 GIT binary patch delta 107 zcmV-x0F?i;1lI(x(E$h^0V51f&IRj}*#Rh4K}keGR2b7^6wv2lAOx5ghyYMUH`n~V zx#lmj1hNQGCNWamP1JL^dI&Q_0NEF+}2W@{jWe4jlL}|Dipz9Gft+U_yxC bUQtGd&%b%No4H=hWB>wBS3j3^P6 Result<(), Error> { @@ -14,7 +16,7 @@ fn main() -> Result<(), Error> { ffmpeg::init()?; // read the input file - if let Ok(mut ictx) = input(&Path::new("input")) { + if let Ok(mut ictx) = input(&Path::new("rgb.png")) { let input = ictx .streams() @@ -48,7 +50,7 @@ fn main() -> Result<(), Error> { // test::print_raw(&rgb_frame.data(0)); // test::print_square(&rgb_frame.data(0), rgb_frame.width() as usize); - test::print_square(&rgb_frame); + out::print_square(&rgb_frame, out::LinesFormat::RightLeft); // test::small_matrix(); } Ok(()) diff --git a/src/out.rs b/src/out.rs new file mode 100644 index 0000000..8fdfcb8 --- /dev/null +++ b/src/out.rs @@ -0,0 +1,74 @@ +use std::io::{stdout, Write}; +use ffmpeg::format::Pixel; + +#[allow(dead_code)] +pub enum LinesFormat { + /// All lines go to the right. + Right, + /// The first line goes to the right, the next to the left. + RightLeft, + /// The first line goes to the left, the next to the right. + LeftRight, + /// All lines go to the left. + Left, +} + +/// Must use square images +pub fn print_square(frame: &ffmpeg::frame::Video, lines_format: LinesFormat) { + if frame.format() != Pixel::RGB24 { panic!("Must use Pixel::RGB24"); } + if frame.width() != frame.height() { panic!("Must be 1:1 aspect ratio"); } + // Not sure if you can stack multiple frames on top of each other or what, + // but we just want the first one. + let z = 0; + + let size = frame.width() as usize; + // How many bytes per pixel RGBA + let linesize = unsafe { std::ptr::addr_of!((*frame.as_ptr()).linesize) }; + let step = (unsafe { *linesize })[z] as usize; + + let mut stdout = stdout(); + let mut lock = stdout.lock(); + + let buf = frame.data(z); + // (Assuming square) Step thru buffer. + for i in 0..size { + let j = i*step; + // Slices non-inclusively, ie: Even though j(n)+step = j(n+1) the ranges don't overlap. It take from..until + let pre_slice = &buf[j..j+step]; + // Only take the size*3 of bytes, ignoring alpha values which are stored after. + // let slice = &pre_slice[0..size*3]; + let mut slice = Vec::from(&pre_slice[0..size*3]); + // let lol = &buf[j..j+step][0..size*3]; + + match lines_format { + LinesFormat::Right => {/* Do nothing */}, + LinesFormat::RightLeft => if i & 1 == 1 { reverse(&mut slice) }, + LinesFormat::LeftRight => if i & 1 != 1 { reverse(&mut slice) }, + LinesFormat::Left => slice.reverse(), + } + + + // DEBUG + // println!("{:?} || {}-{}", slice, j, j+step); + // NORMAL + lock.write(&slice).unwrap(); + } + stdout.flush().unwrap(); +} + + +/// Reverses the order of every grouping of 3 bytes. +fn reverse(raw: & mut [u8]) { + // I would prefer this only went over the elements once, + // not twice. + + let x = raw + .iter() + .array_chunks::<3>() + .rev() + .flatten() + .map(|f| *f) + .collect::>(); + + x.iter().enumerate().for_each(|f| raw[f.0] = *f.1); +} \ No newline at end of file diff --git a/src/test.rs b/src/test.rs deleted file mode 100644 index 1a83e6f..0000000 --- a/src/test.rs +++ /dev/null @@ -1,38 +0,0 @@ -use std::io::{stdout, Write}; -use ffmpeg::format::Pixel; - -/// Must use square images -// pub fn print_square(buf: &[u8], width_hight: usize, line) { -pub fn print_square(frame: &ffmpeg::frame::Video) { - if frame.format() != Pixel::RGB24 { panic!("Must use Pixel::RGB24"); } - if frame.width() != frame.height() { panic!("Must be square aspect ratio"); } - // Not sure if you can stack multiple frames on top of each other or what, - // but we just want the first one. - let z = 0; - - let buf = frame.data(z); - let size = frame.width() as usize; - // How many bytes per pixel RGBA - let linesize = unsafe { std::ptr::addr_of!((*frame.as_ptr()).linesize) }; - let step = (unsafe { *linesize })[z] as usize; - - let mut stdout = stdout(); - let mut lock = stdout.lock(); - - // (Assuming square) Step thru buffer. - for i in 0..size { - let j = i*step; - // Slices non-inclusively, ie: Even though j(n)+step = j(n+1) the ranges don't overlap. It take from..until - let pre_slice = &buf[j..j+step]; - // Only take the size*3 of bytes, ignoring alpha values which are stored after. - let slice = &pre_slice[0..size*3]; - // let lol = &buf[j..j+step][0..size*3]; - - // DEBUG - // println!("{:?} || {}-{}", slice, j, j+step); - // NORMAL - lock.write(slice).unwrap(); - } - stdout.flush().unwrap(); -} -