diff --git a/src/ascii_manipulation.rs b/src/ascii_manipulation.rs index 3b35379..d6bd24d 100644 --- a/src/ascii_manipulation.rs +++ b/src/ascii_manipulation.rs @@ -1,15 +1,35 @@ +//! This module contains all functions related to converting images to ASCII. use std::process::exit; use image::{DynamicImage, GenericImageView, Rgba}; use log::error; use crate::model_rgb_ascii::Ascii; +/// This constant is used to calculate braille values. const BRAILLE_TABLE: [[u8; 2]; 4] = [[1u8, 8u8], [2u8, 16u8], [4u8, 32u8], [64u8, 128u8]]; +/// This function returns the colour depth of an input pixel. +/// +/// It does so using the luminosity method +/// (0.3*r + 0.59*g + 0.11*b) +/// +/// arguments: +/// pixel: Rgba - pixel to return colour from +/// +/// returns: +/// u8 representing colour depth of pixel fn get_color(pixel: Rgba) -> u8 { //luminosity method of getting lightness (pixel[0] as f32 * 0.3 + pixel[1] as f32 * 0.59 + pixel[2] as f32 * 0.11) as u8 } +/// This function converts a given image into ASCII. +/// +/// arguments: +/// char_map: String - the characters to convert the image into +/// image: DynamicImage - the image to convert into char_map's characters +/// +/// returns: +/// Vec> containing the converted image fn to_ascii(char_map: String, image: DynamicImage) -> Vec> { let l = char_map.len() as f32; let mut str: Vec = Vec::new(); @@ -27,14 +47,40 @@ fn to_ascii(char_map: String, image: DynamicImage) -> Vec> { out } +/// This wrapper function converts an image to standard ASCII. +/// +/// It uses the char_map " .:-=+*#%@" +/// +/// arguments: +/// image: DynamicImage - the image to convert +/// +/// returns: +/// Vec> containing the converted image pub fn to_simple_ascii(image: DynamicImage) -> Vec> { to_ascii(" .:-=+*#%@".to_owned(), image) } +/// This wrapper function converts an image to extended ASCII. +/// +/// It uses the char_map " .'`^",:;Il!i><~+_-?][}{1)(|\/tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$" +/// +/// arguments: +/// image: DynamicImage - the image to convert +/// +/// returns: +/// Vec> containing the converted image pub fn to_complex_ascii(image: DynamicImage) -> Vec> { to_ascii(" .'`^\",:;Il!i><~+_-?][}{1)(|\\/tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$".to_owned(), image) } +/// This wrapper function converts an image to custom ASCII. +/// +/// arguments: +/// char_map: String - the custom character map to convert image into +/// image: DynamicImage - the image to convert +/// +/// returns: +/// Vec> containing the converted image pub fn to_custom_ascii(char_map: String, image: DynamicImage) -> Vec> { if char_map.is_empty() { error!("Custom map can not be empty!"); @@ -43,6 +89,13 @@ pub fn to_custom_ascii(char_map: String, image: DynamicImage) -> Vec> to_ascii(char_map, image) } +/// This function converts an image to braille ASCII. +/// +/// arguments: +/// image: DynamicImage - the image to convert +/// +/// returns: +/// Vec> containing the converted image pub fn to_braille_ascii(image: DynamicImage, threshold: u8) -> Vec> { let mut str: Vec = Vec::new(); let mut out: Vec> = Vec::new(); diff --git a/src/cli.rs b/src/cli.rs index 6e5e209..520bc5c 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,3 +1,6 @@ +//! This module contains all functions related to the CLI part of the program. +//! +//! It manages and validates flags, mostly. use std::ffi::OsString; use std::path::PathBuf; use std::process::exit; @@ -55,6 +58,9 @@ pub struct Cli { impl Cli { + /// This function prints all parts of Cli. + /// + /// used for debugging. pub fn debug_print(&self) { debug!("complex: {}", self.complex); debug!("colour: {}", self.colour); @@ -75,6 +81,13 @@ impl Cli { } } + /// This function validates various parts of Cli. + /// + /// It checks that: + /// * image exists + /// * image has the proper extension + /// * output file (if Some) does not exist + /// * map (if Some) contains ASCII-only characters pub fn validate(&self) { if !file_exists(&self.image) { error!("Input file \"{}\" does not exist!", self.image.display()); @@ -101,6 +114,7 @@ impl Cli { } } + /// This function initializes logging (dependent on cli.debug flag) pub fn init(&self) { if self.debug {std::env::set_var("RUST_LOG", "trace")} env_logger::init(); diff --git a/src/image_manipulation.rs b/src/image_manipulation.rs index fee4141..db2b151 100644 --- a/src/image_manipulation.rs +++ b/src/image_manipulation.rs @@ -1,3 +1,4 @@ +//! This module contains all functions related to image manipulation. use termion::terminal_size; use log::{debug, error}; use std::process::exit; @@ -5,6 +6,10 @@ use std::path::PathBuf; use image::DynamicImage; use image::imageops::FilterType; +/// This function returns the (width, length) of stdout +/// +/// returns: +/// (u32, u32) representing the (width, length) of stdout fn get_terminal_size() -> (u32, u32) { let size = terminal_size(); match size { @@ -18,6 +23,18 @@ fn get_terminal_size() -> (u32, u32) { } } +/// This function resizes a given image to one of multiple options. +/// +/// if full, braille and opt_w are all false/None, resizes according to height of stdout. +/// +/// arguments: +/// img: DynamicImage - the image to be resized +/// full: bool - if true, resizes to stdout width +/// braille: bool - if true, increases size of image by 2x4, for braille processing +/// opt_w: Option - if Some, resizes to the given width +/// +/// returns: +/// DynamicImage, resized pub fn resize_image(img: DynamicImage, full: bool, braille: bool, opt_w: Option) -> DynamicImage { //compiler complains that these v values are never read; this is true, however they are necessary because otherwise the program simply will not compile. let (mut w, mut h) = (1,1); @@ -47,6 +64,13 @@ pub fn resize_image(img: DynamicImage, full: bool, braille: bool, opt_w: Option< img.resize_exact(w, h, FilterType::CatmullRom) } +/// This function opens an image into an ImageBuffer. +/// +/// arguments: +/// path: PathBuf - Path to the image file to open +/// +/// returns: +/// DynamicImage buffer pub fn open_image(path: PathBuf) -> DynamicImage { let img = image::open(path); match img { diff --git a/src/main.rs b/src/main.rs index e0d2550..a2b3d37 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +//! Driver module. #![feature(file_create_new)] use clap::Parser; @@ -14,10 +15,13 @@ mod output; mod model_rgb_ascii; //todo: general -/* Documentation * Readme */ + +/// This is the main function. +/// +/// It drives the CLI module, calls the appropriate convert functions and directs output. fn main() { std::env::set_var("RUST_LOG", "info"); diff --git a/src/model_rgb_ascii.rs b/src/model_rgb_ascii.rs index a2546bc..147e494 100644 --- a/src/model_rgb_ascii.rs +++ b/src/model_rgb_ascii.rs @@ -1,9 +1,22 @@ +//! This module contains the Ascii struct. + +/// This struct represents one character + rgb colour. pub struct Ascii { pub char: char, pub rgb: [u8; 3], } impl Ascii { + /// This function creates a new Ascii instance. + /// + /// Arguments: + /// ch: u8 - the character + /// r: u8 - Red colour value + /// g: u8 - Green colour value + /// b: u8 - Blue colour value + /// + /// returns: + /// self pub fn new(ch: u8, r: u8, g: u8, b: u8) -> Self { Ascii { char: char::from(ch), diff --git a/src/output.rs b/src/output.rs index b15b46d..db73cd9 100644 --- a/src/output.rs +++ b/src/output.rs @@ -1,3 +1,4 @@ +//! This module contains functions related to output. use std::fs::File; use std::io::Write; use std::path::PathBuf; @@ -6,6 +7,11 @@ use log::error; use termion::{color, style}; use crate::model_rgb_ascii::Ascii; +/// This function prints ASCII art to stdout. +/// +/// arguments: +/// art: Vec> - vector of vectors representing the art +/// in_colour: bool - whether to print in colour or as hard white pub fn print_terminal(art: Vec>, in_colour: bool) { for line in art { for ascii in line { @@ -19,6 +25,14 @@ pub fn print_terminal(art: Vec>, in_colour: bool) { } } +/// This function prints ASCII art to a file. +/// +/// arguments: +/// art: Vec> - vector of vectors representing the art +/// out: PathBuf - the path of the out file +/// +/// returns: +/// () if everything goes smoothly, Err otherwise fn _print_file(art: Vec>, out: PathBuf) -> std::io::Result<()> { let mut file = File::create_new(out)?; for line in art { @@ -30,6 +44,11 @@ fn _print_file(art: Vec>, out: PathBuf) -> std::io::Result<()> { Ok(()) } +/// This is a wrapper function for _print_file(). It handles any errors that _print_file() throws up. +/// +/// arguments: +/// art: Vec> - vector of vectors representing the art +/// out: PathBuf - the path of the out file pub fn print_file(art: Vec>, out: PathBuf) { if let Err(e) = _print_file(art, out) { error!("Failed to write to file: {}", e.to_string());