simple_gal/imaging/params.rs
1//! Parameter types for image operations.
2//!
3//! These structs describe *what* to do, not *how* to do it. They are the
4//! interface between the high-level [`operations`](super::operations) module
5//! (which decides what images to create) and the [`backend`](super::backend)
6//! (which does the actual pixel work). This separation allows swapping backends
7//! (e.g. for testing with a mock) without changing operation logic.
8//!
9//! ## Types
10//!
11//! - [`Quality`] — Lossy encoding quality (1–100, default 90). Clamped on construction.
12//! - [`Sharpening`] — Unsharp-mask parameters (sigma + threshold) for thumbnail crispness.
13//! - [`ResizeParams`] — Full specification for a resize: source, output path, target dimensions, quality.
14//! - [`ThumbnailParams`] — Full specification for a thumbnail: source, output, crop dimensions, quality, optional sharpening.
15
16use std::path::PathBuf;
17
18/// Quality setting for lossy image encoding (1-100).
19#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20pub struct Quality(pub u32);
21
22impl Quality {
23 pub fn new(value: u32) -> Self {
24 Self(value.clamp(1, 100))
25 }
26
27 pub fn value(self) -> u32 {
28 self.0
29 }
30}
31
32impl Default for Quality {
33 fn default() -> Self {
34 Self(90)
35 }
36}
37
38/// Sharpening parameters for unsharp mask.
39///
40/// - `sigma`: Standard deviation of the Gaussian blur (higher = more sharpening)
41/// - `threshold`: Minimum brightness difference to sharpen (0 = sharpen all pixels)
42#[derive(Debug, Clone, Copy, PartialEq)]
43pub struct Sharpening {
44 pub sigma: f32,
45 pub threshold: i32,
46}
47
48impl Sharpening {
49 /// Light sharpening suitable for thumbnails.
50 pub fn light() -> Self {
51 Self {
52 sigma: 0.5,
53 threshold: 0,
54 }
55 }
56}
57
58/// Parameters for a simple resize operation.
59#[derive(Debug, Clone, PartialEq)]
60pub struct ResizeParams {
61 pub source: PathBuf,
62 pub output: PathBuf,
63 pub width: u32,
64 pub height: u32,
65 pub quality: Quality,
66}
67
68/// Parameters for a thumbnail operation (resize + center crop).
69#[derive(Debug, Clone, PartialEq)]
70pub struct ThumbnailParams {
71 pub source: PathBuf,
72 pub output: PathBuf,
73 /// Final crop dimensions.
74 pub crop_width: u32,
75 pub crop_height: u32,
76 pub quality: Quality,
77 pub sharpening: Option<Sharpening>,
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83
84 #[test]
85 fn quality_clamps_to_valid_range() {
86 assert_eq!(Quality::new(0).value(), 1);
87 assert_eq!(Quality::new(50).value(), 50);
88 assert_eq!(Quality::new(150).value(), 100);
89 }
90
91 #[test]
92 fn quality_default_is_90() {
93 assert_eq!(Quality::default().value(), 90);
94 }
95
96 #[test]
97 fn sharpening_light_values() {
98 let s = Sharpening::light();
99 assert_eq!(s.sigma, 0.5);
100 assert_eq!(s.threshold, 0);
101 }
102}