choose your screen type
This commit is contained in:
parent
985448c4e8
commit
fdb3de89a9
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
/target
|
||||
/.vscode
|
||||
*.png
|
||||
|
BIN
input → rgb.png
BIN
input → rgb.png
Binary file not shown.
Before Width: | Height: | Size: 563 B After Width: | Height: | Size: 599 B |
@ -1,3 +1,5 @@
|
||||
#![feature(iter_array_chunks)]
|
||||
|
||||
extern crate ffmpeg_next as ffmpeg;
|
||||
|
||||
use anyhow::Error;
|
||||
@ -6,7 +8,7 @@ use ffmpeg::media::Type;
|
||||
use ffmpeg::software::scaling::{context::Context, flag::Flags};
|
||||
use ffmpeg::util::frame::video::Video;
|
||||
use std::path::Path;
|
||||
mod test;
|
||||
mod out;
|
||||
|
||||
fn main() -> 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(())
|
||||
|
74
src/out.rs
Normal file
74
src/out.rs
Normal file
@ -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::<Vec<u8>>();
|
||||
|
||||
x.iter().enumerate().for_each(|f| raw[f.0] = *f.1);
|
||||
}
|
38
src/test.rs
38
src/test.rs
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user