Initial commit
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | /target | ||||||
							
								
								
									
										1196
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										1196
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										10
									
								
								Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								Cargo.toml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | [package] | ||||||
|  | name = "yabinary" | ||||||
|  | version = "0.1.0" | ||||||
|  | edition = "2021" | ||||||
|  |  | ||||||
|  | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||||||
|  |  | ||||||
|  | [dependencies] | ||||||
|  | clap = { version = "4.5.9", features = ["derive"] } | ||||||
|  | image = "0.25.2" | ||||||
							
								
								
									
										107
									
								
								src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								src/main.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,107 @@ | |||||||
|  | use clap::{Parser, ValueEnum}; | ||||||
|  | use image::ImageReader; | ||||||
|  | use std::fs::File; | ||||||
|  | use std::io::{Read, Write}; | ||||||
|  | use std::path::PathBuf; | ||||||
|  |  | ||||||
|  | const WHITE: u8 = 0x88; | ||||||
|  | const BLACK: u8 = 0xCC; | ||||||
|  | const SCREEN_WIDTH: usize = 16; | ||||||
|  |  | ||||||
|  | #[derive(ValueEnum, Clone, Copy)] | ||||||
|  | enum Color { | ||||||
|  |     White, | ||||||
|  |     Black, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl Color { | ||||||
|  |     fn as_bytes(&self) -> u8 { | ||||||
|  |         match self { | ||||||
|  |             Color::White => WHITE, | ||||||
|  |             Color::Black => BLACK, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl std::fmt::Display for Color { | ||||||
|  |     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||||
|  |         match self { | ||||||
|  |             Self::White => f.write_str("white"), | ||||||
|  |             Self::Black => f.write_str("black"), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[derive(Parser)] | ||||||
|  | struct Cli { | ||||||
|  |     #[arg(long, requires_all=["header_lines"])] | ||||||
|  |     header_from: Option<PathBuf>, | ||||||
|  |  | ||||||
|  |     #[arg(long)] | ||||||
|  |     header_lines: Option<usize>, | ||||||
|  |  | ||||||
|  |     image: PathBuf, | ||||||
|  |  | ||||||
|  |     #[arg(long, requires_all=["footer_lines"])] | ||||||
|  |     footer_from: Option<PathBuf>, | ||||||
|  |  | ||||||
|  |     #[arg(long)] | ||||||
|  |     footer_lines: Option<usize>, | ||||||
|  |  | ||||||
|  |     #[arg(long, default_value_t = Color::White)] | ||||||
|  |     background: Color, | ||||||
|  |  | ||||||
|  |     output: PathBuf, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fn main() -> Result<(), Box<dyn std::error::Error>> { | ||||||
|  |     let c = Cli::parse(); | ||||||
|  |  | ||||||
|  |     let img = ImageReader::open(c.image)?.decode()?; | ||||||
|  |  | ||||||
|  |     if SCREEN_WIDTH < img.width() as usize { | ||||||
|  |         println!( | ||||||
|  |             "WARN: {} pixels are ignored", | ||||||
|  |             img.width() as usize - SCREEN_WIDTH | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     let mut output = File::create(&c.output)?; | ||||||
|  |  | ||||||
|  |     if let Some(header_path) = c.header_from { | ||||||
|  |         let mut buffer = vec![0; c.header_lines.unwrap() * SCREEN_WIDTH]; | ||||||
|  |         File::open(header_path)?.read_exact(&mut buffer)?; | ||||||
|  |         output.write(&buffer)?; | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     for row in img.to_rgba8().rows() { | ||||||
|  |         let buffer: Vec<_> = (0..SCREEN_WIDTH) | ||||||
|  |             .into_iter() | ||||||
|  |             .zip( | ||||||
|  |                 row.into_iter() | ||||||
|  |                     .map(|v| { | ||||||
|  |                         let brightness = | ||||||
|  |                             (v[0] as f32 / 256.0 + v[1] as f32 / 256.0 + v[2] as f32 / 256.0) / 3.0; | ||||||
|  |  | ||||||
|  |                         if brightness > 0.2 { | ||||||
|  |                             Color::White | ||||||
|  |                         } else { | ||||||
|  |                             Color::Black | ||||||
|  |                         } | ||||||
|  |                     }) | ||||||
|  |                     .chain(std::iter::repeat(c.background)), | ||||||
|  |             ) | ||||||
|  |             .map(|(_, color)| color.as_bytes()) | ||||||
|  |             .collect(); | ||||||
|  |  | ||||||
|  |         output.write(&buffer)?; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if let Some(footer_path) = c.footer_from { | ||||||
|  |         let mut buffer = vec![0; c.footer_lines.unwrap() * SCREEN_WIDTH]; | ||||||
|  |         File::open(footer_path)?.read_exact(&mut buffer)?; | ||||||
|  |         output.write(&buffer)?; | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     Ok(()) | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user