feat: wire up image conversion pipeline and CLI

Add `convert.rs`: a SIMD nearest-color search and a rayon-parallel
`nordify_pixels` function. Add `error.rs` with the `NordifyError` type.

Rewrite `lib.rs` to expose `NordifyOptions`, `nordify_image`, and
`nordify_file` as the public API. Rewrite `main.rs` to parse CLI
arguments with `argh` and call into `lib.rs`.

Add `argh` and `thiserror` as dependencies.
This commit is contained in:
2026-08-28 13:41:18 +02:00
parent 4cbc25f2d6
commit 28dac1b7dc
5 changed files with 497 additions and 4 deletions
+44 -2
View File
@@ -1,3 +1,45 @@
fn main() {
println!("Hello, world!");
use std::path::PathBuf;
/// Convert an image to the Nord color palette without dithering artifacts.
#[derive(argh::FromArgs)]
struct Args {
/// input image path
#[argh(positional)]
input: PathBuf,
/// output image path
#[argh(option, short = 'o')]
output: PathBuf,
/// use only the original 16 Nord colors (disable palette expansion)
#[argh(switch)]
no_expand: bool,
/// number of interpolated colors between close palette entries (default: 3)
#[argh(option, default = "3")]
expansion_factor: usize,
/// use plain RGB distance instead of perceptual LAB distance
#[argh(switch)]
rgb_distance: bool,
}
fn main() -> std::process::ExitCode {
let args: Args = argh::from_env();
let options = nordify_rs::NordifyOptions {
expand: !args.no_expand,
expansion_factor: args.expansion_factor,
use_lab: !args.rgb_distance,
};
match nordify_rs::nordify_file(&args.input, &args.output, &options) {
Ok(()) => {
println!("Saved to {}", args.output.display());
std::process::ExitCode::SUCCESS
}
Err(err) => {
eprintln!("Error: {err}");
std::process::ExitCode::FAILURE
}
}
}