about summary refs log tree commit diff
path: root/squash/src
diff options
context:
space:
mode:
Diffstat (limited to 'squash/src')
-rw-r--r--squash/src/cli.rs27
-rw-r--r--squash/src/main.rs31
2 files changed, 55 insertions, 3 deletions
diff --git a/squash/src/cli.rs b/squash/src/cli.rs
index ba1658a..e33015e 100644
--- a/squash/src/cli.rs
+++ b/squash/src/cli.rs
@@ -10,12 +10,14 @@ const AUTHORS: &str = env!("CARGO_PKG_AUTHORS");
 pub struct Cli {
 	pub color_count: u8,
 	pub tolerance: Option<f32>,
+	pub scale: u8,
 	pub selector: Selector,
 	pub difference: &'static DiffFn,
 	pub input: Utf8PathBuf,
 	pub in_type: InType,
 	pub output: Utf8PathBuf,
 	pub out_type: OutType,
+	pub verbose: bool,
 }
 
 // It's not a builder, but I think the builder/building name is useful
@@ -24,8 +26,10 @@ pub struct Cli {
 struct BuildingCli {
 	pub color_count: Option<u8>,
 	pub tolerance: Option<f32>,
+	pub scale: Option<u8>,
 	pub difference: DifferenceFn,
 	pub selector: Selector,
+	pub verbose: bool,
 }
 
 impl BuildingCli {
@@ -70,11 +74,13 @@ impl BuildingCli {
 			color_count: self.color_count.unwrap_or(Self::DEFAULT_COLORS),
 			tolerance: self.tolerance,
 			selector: self.selector,
+			scale: self.scale.unwrap_or(25),
 			difference,
 			input,
 			in_type,
 			output,
 			out_type,
+			verbose: self.verbose,
 		}
 	}
 }
@@ -150,6 +156,19 @@ pub fn build() -> Cli {
 					building.tolerance = Some(tol);
 				}
 			},
+			Some(("scale", scale)) => match scale.parse::<u8>() {
+				Err(_) => {
+					eprintln!("scale must be >= 1 and <= 100");
+					std::process::exit(1);
+				}
+				Ok(scale) if scale < 1 || scale > 100 => {
+					eprintln!("scale must be >= 1 and <= 100");
+					std::process::exit(1);
+				}
+				Ok(scale) => {
+					building.scale = Some(scale);
+				}
+			},
 			Some(("difference", algo)) | Some(("dif", algo)) => match algo {
 				"rgb" => building.difference = DifferenceFn::Rgb,
 				"redmean" => building.difference = DifferenceFn::Redmean,
@@ -166,6 +185,9 @@ pub fn build() -> Cli {
 					std::process::exit(1);
 				}
 			},
+			Some(("loud", _)) | Some(("verbose", _)) => {
+				building.verbose = true;
+			}
 			Some(("help", "algorithms")) => print_help_algorithms(),
 			Some(("help", "selectors")) => print_help_selectors(),
 			Some(("help", _)) => print_help(),
@@ -199,6 +221,9 @@ fn print_help() -> ! {
 	println!("        the number of colours the final image should contain");
 	println!("        a whole number more than 0 and less than, or equal, 256");
 	println!("        [Default 256]\n");
+	println!("    scale=<int>");
+	println!("        the percent of pixels to consider when selecting the palette");
+	println!("        for the image. Whole number 1 to 100, inclusive. [Default 25]\n");
 	println!("    difference=<algorithm> | dif=<algorithm>");
 	println!("        the color comparison function to use. one of: rgb, redmean");
 	println!("        for more details use help=algorithms. [Default rgb]\n");
@@ -209,6 +234,8 @@ fn print_help() -> ! {
 	println!("        how different colours should be to be added to the palette");
 	println!("        only sort/select usese this value.");
 	println!("        a number > 0 and <= 100 [Default 3]\n");
+	println!("    loud= | verbose=");
+	println!("        print information about the image and palette.\n");
 	println!("    help= | -h | --help");
 	println!("        print this message and exit\n");
 	println!("    version= | -V | --version");
diff --git a/squash/src/main.rs b/squash/src/main.rs
index 24d557f..c0cea51 100644
--- a/squash/src/main.rs
+++ b/squash/src/main.rs
@@ -1,3 +1,5 @@
+use std::time::Duration;
+
 use colorsquash::{
 	selection::{Kmeans, SortSelect},
 	SquasherBuilder,
@@ -34,11 +36,24 @@ fn main() -> Result<(), anyhow::Error> {
 		cli::Selector::Kmeans => builder = builder.selector(Kmeans { max_iter: 10 }),
 	};
 
-	let start = std::time::Instant::now();
-	let mut squasher = builder.build(&image.data);
-	println!("{:.2}ms", start.elapsed().as_secs_f32());
+	let mut start = std::time::Instant::now();
+	let mut squasher = builder.scale(cli.scale).build(&image.data);
+
+	if cli.verbose {
+		println!(
+			"Palette is {} colors.\nSelection took {}",
+			squasher.palette().len(),
+			human_time(start.elapsed())
+		);
+	}
 
+	start = std::time::Instant::now();
 	let size = squasher.map_over(&mut image.data);
+
+	if cli.verbose {
+		println!("Mapping took {}", human_time(start.elapsed()));
+	}
+
 	image.data.resize(size, 0);
 
 	match cli.out_type {
@@ -46,3 +61,13 @@ fn main() -> Result<(), anyhow::Error> {
 		OutType::Gif => image::save_gif(image, squasher, cli.output),
 	}
 }
+
+fn human_time(duration: Duration) -> String {
+	if duration.as_secs() > 0 {
+		format!("{:.2}s", duration.as_secs_f32())
+	} else if duration.as_millis() >= 10 {
+		format!("{}ms", duration.as_millis())
+	} else {
+		format!("{}μs", duration.as_micros())
+	}
+}