Skip to content

Commit

Permalink
add double-pixel pixel-format
Browse files Browse the repository at this point in the history
  • Loading branch information
swz-git committed Oct 1, 2023
1 parent 2b0c115 commit aed0998
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 24 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ ctrlc = "3.2.5"
unix-named-pipe = "0.2.0"
uuid = { version = "1.3.0", features = ["fast-rng", "v4"] }
which = "4.4.0"
y4m = "0.7.0"
y4m = "0.8.0"
yansi = "0.5.1"
58 changes: 41 additions & 17 deletions src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ where

// thank chat gpt for this
fn yuv_to_rgb(y: f64, u: f64, v: f64) -> (u8, u8, u8) {
let y = y * 255.0;
// let y = y * 255.0;
let u = u - 128.0;
let v = v - 128.0;

Expand All @@ -38,49 +38,73 @@ pub fn display(
display_chars: &[char],
colored: bool,
pixel_style: PixelStyle,
cols: u16,
) -> Result<(), Box<dyn Error>> {
let mut term = Term::stdout();
let mut buf = String::new();

let last_color = Color::Unset;

let y_plane = frame.get_y_plane();
let u_plane = frame.get_u_plane();
let v_plane = frame.get_v_plane();

for (i, y_value) in y_plane.iter().enumerate() {
let rgb = yuv_to_rgb(
*y_value as f64 / u8::MAX as f64,
u_plane[i] as f64,
v_plane[i] as f64,
);
// dbg!(rgb, (*y_value, u_plane[i], v_plane[i]));
let mut new_color = match colored {
let row = i / (cols as usize);
if row % 2 != 1 && pixel_style == PixelStyle::DoublePixel {
continue; // when pixel_style is DoublePixel, ffmpeg outputs double the rows
}

let color_above = match pixel_style {
PixelStyle::DoublePixel => Some({
let index_of_above = (row - 1) * cols as usize + (i % cols as usize);
let y_value = &y_plane[index_of_above];
match colored {
false => Color::RGB(*y_value, *y_value, *y_value),
true => {
let rgb = yuv_to_rgb(
*y_value as f64,
u_plane[index_of_above] as f64,
v_plane[index_of_above] as f64,
);
Color::RGB(rgb.0, rgb.1, rgb.2)
}
}
}),
_ => None,
};

let color = match colored {
false => Color::RGB(*y_value, *y_value, *y_value),
true => Color::RGB(rgb.0, rgb.1, rgb.2),
true => {
let rgb = yuv_to_rgb(*y_value as f64, u_plane[i] as f64, v_plane[i] as f64);
Color::RGB(rgb.0, rgb.1, rgb.2)
}
};
if new_color == last_color {
new_color = Color::Unset
}

match pixel_style {
PixelStyle::Char => {
Style::new(Color::Unset)
.bg(Color::Black)
.fg(new_color)
.fg(color)
.fmt_prefix(&mut buf)?;
}
PixelStyle::Pixel => {
Style::new(Color::Unset)
.fg(new_color)
.bg(new_color)
.fg(color)
.bg(color)
.fmt_prefix(&mut buf)?;
}
PixelStyle::DoublePixel => {
Style::new(Color::Unset)
.fg(color)
.bg(color_above.unwrap_or(color))
.fmt_prefix(&mut buf)?;
}
}

let color = match pixel_style {
PixelStyle::Char => get_item_from_brightness(y_value, display_chars),
PixelStyle::Pixel => ' ',
PixelStyle::DoublePixel => '▄',
}
.to_string();
buf.write_str(&color)?;
Expand Down
19 changes: 15 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ use display::display;
const ASCII_BY_BRIGHTNESS: &str =
r#"$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,"^`'. "#;

#[derive(clap::ValueEnum, Clone, Copy, Debug)]
#[derive(clap::ValueEnum, Clone, Copy, Debug, PartialEq)]
pub enum PixelStyle {
Char,
Pixel,
DoublePixel,
}

#[derive(clap::ValueEnum, Clone, Copy, Debug)]
Expand Down Expand Up @@ -124,7 +125,11 @@ fn main() -> Result<(), Box<dyn Error>> {

let term_size = term.size();

let ffmpeg_res = (term_size.1, term_size.0);
let ffmpeg_res = if args.pixel_style == PixelStyle::DoublePixel {
(term_size.1, term_size.0 * 2)
} else {
(term_size.1, term_size.0)
};

let maybe_audio_pipe_path: Option<PathBuf> = if cfg!(unix) && args.audio {
Some(Path::join(
Expand Down Expand Up @@ -153,7 +158,12 @@ fn main() -> Result<(), Box<dyn Error>> {
"".into()
},
format!(
"scale=iw*2:ih,scale={}:{}:force_original_aspect_ratio={},{},format=yuv444p",
"scale=iw*2:ih{},scale={}:{}:force_original_aspect_ratio={},{},format=yuv444p",
if args.pixel_style == PixelStyle::DoublePixel {
"*2"
} else {
""
},
ffmpeg_res.0,
ffmpeg_res.1,
match args.display_mode {
Expand Down Expand Up @@ -215,7 +225,7 @@ fn main() -> Result<(), Box<dyn Error>> {
.ok_or("Failed to read stdout of ffmpeg")?;
let reader = BufReader::new(proc_stdout);

let mut dec = y4m::decode(reader)?;
let mut dec = y4m::Decoder::new(reader)?;

// You need to enable ansi stuff on windows smh
Paint::enable_windows_ascii();
Expand All @@ -239,6 +249,7 @@ fn main() -> Result<(), Box<dyn Error>> {
&ASCII_BY_BRIGHTNESS.chars().collect::<Vec<char>>(),
args.color,
args.pixel_style,
term_size.1, // cols
)?;

i += 1;
Expand Down

0 comments on commit aed0998

Please sign in to comment.