sklears_compose/cv_pipelines/
processing_configuration.rs

1//! Processing configuration and quality settings
2//!
3//! This module provides comprehensive configuration structures for computer vision
4//! processing including quality settings, performance optimization, parallel processing,
5//! memory management, and caching strategies.
6
7use super::types_config::{
8    CacheEvictionPolicy, LoadBalancingAlgorithm, MemoryOptimizationLevel, ParallelStrategy,
9    ProcessingComplexity, RecoveryStrategy, TransformParameter,
10};
11use serde::{Deserialize, Serialize};
12use std::collections::HashMap;
13use std::time::Duration;
14
15/// Quality settings for computer vision processing
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct QualitySettings {
18    /// Overall quality level
19    pub quality_level: ProcessingComplexity,
20    /// Compression configuration
21    pub compression: CompressionConfig,
22    /// Noise reduction settings
23    pub noise_reduction: NoiseReductionConfig,
24    /// Sharpening configuration
25    pub sharpening: SharpeningConfig,
26    /// Color correction settings
27    pub color_correction: ColorCorrectionConfig,
28    /// Quality assurance settings
29    pub quality_assurance: QualityAssuranceConfig,
30}
31
32impl Default for QualitySettings {
33    fn default() -> Self {
34        Self {
35            quality_level: ProcessingComplexity::Medium,
36            compression: CompressionConfig::default(),
37            noise_reduction: NoiseReductionConfig::default(),
38            sharpening: SharpeningConfig::default(),
39            color_correction: ColorCorrectionConfig::default(),
40            quality_assurance: QualityAssuranceConfig::default(),
41        }
42    }
43}
44
45impl QualitySettings {
46    /// Create high-quality settings
47    #[must_use]
48    pub fn high_quality() -> Self {
49        Self {
50            quality_level: ProcessingComplexity::High,
51            compression: CompressionConfig::lossless(),
52            noise_reduction: NoiseReductionConfig::aggressive(),
53            sharpening: SharpeningConfig::enhanced(),
54            color_correction: ColorCorrectionConfig::accurate(),
55            quality_assurance: QualityAssuranceConfig::strict(),
56        }
57    }
58
59    /// Create performance-optimized settings
60    #[must_use]
61    pub fn performance_optimized() -> Self {
62        Self {
63            quality_level: ProcessingComplexity::Low,
64            compression: CompressionConfig::fast(),
65            noise_reduction: NoiseReductionConfig::basic(),
66            sharpening: SharpeningConfig::minimal(),
67            color_correction: ColorCorrectionConfig::basic(),
68            quality_assurance: QualityAssuranceConfig::lenient(),
69        }
70    }
71
72    /// Create balanced settings
73    #[must_use]
74    pub fn balanced() -> Self {
75        Self::default()
76    }
77}
78
79/// Compression configuration for image processing
80#[derive(Debug, Clone, Serialize, Deserialize)]
81pub struct CompressionConfig {
82    /// Enable compression
83    pub enabled: bool,
84    /// Compression algorithm
85    pub algorithm: CompressionAlgorithm,
86    /// Quality level (0-100, higher is better quality)
87    pub quality: u8,
88    /// Enable progressive encoding
89    pub progressive: bool,
90    /// Optimize for file size
91    pub optimize_size: bool,
92    /// Custom compression parameters
93    pub custom_params: HashMap<String, TransformParameter>,
94}
95
96impl Default for CompressionConfig {
97    fn default() -> Self {
98        Self {
99            enabled: true,
100            algorithm: CompressionAlgorithm::JPEG,
101            quality: 85,
102            progressive: true,
103            optimize_size: false,
104            custom_params: HashMap::new(),
105        }
106    }
107}
108
109impl CompressionConfig {
110    /// Create lossless compression configuration
111    #[must_use]
112    pub fn lossless() -> Self {
113        Self {
114            enabled: true,
115            algorithm: CompressionAlgorithm::PNG,
116            quality: 100,
117            progressive: false,
118            optimize_size: false,
119            custom_params: HashMap::new(),
120        }
121    }
122
123    /// Create fast compression configuration
124    #[must_use]
125    pub fn fast() -> Self {
126        Self {
127            enabled: true,
128            algorithm: CompressionAlgorithm::JPEG,
129            quality: 70,
130            progressive: false,
131            optimize_size: true,
132            custom_params: HashMap::new(),
133        }
134    }
135}
136
137/// Compression algorithms for image processing
138#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
139pub enum CompressionAlgorithm {
140    /// JPEG compression
141    JPEG,
142    /// PNG compression
143    PNG,
144    /// WebP compression
145    WebP,
146    /// HEIF compression
147    HEIF,
148    /// AVIF compression
149    AVIF,
150    /// Custom compression
151    Custom,
152}
153
154impl Default for CompressionAlgorithm {
155    fn default() -> Self {
156        Self::JPEG
157    }
158}
159
160/// Noise reduction configuration
161#[derive(Debug, Clone, Serialize, Deserialize)]
162pub struct NoiseReductionConfig {
163    /// Enable noise reduction
164    pub enabled: bool,
165    /// Denoising algorithm
166    pub algorithm: DenoisingAlgorithm,
167    /// Noise reduction strength (0.0-1.0)
168    pub strength: f64,
169    /// Preserve edges while denoising
170    pub preserve_edges: bool,
171    /// Preserve fine details
172    pub preserve_details: bool,
173    /// Custom denoising parameters
174    pub custom_params: HashMap<String, TransformParameter>,
175}
176
177impl Default for NoiseReductionConfig {
178    fn default() -> Self {
179        Self {
180            enabled: true,
181            algorithm: DenoisingAlgorithm::BilateralFilter,
182            strength: 0.5,
183            preserve_edges: true,
184            preserve_details: true,
185            custom_params: HashMap::new(),
186        }
187    }
188}
189
190impl NoiseReductionConfig {
191    /// Create aggressive noise reduction configuration
192    #[must_use]
193    pub fn aggressive() -> Self {
194        Self {
195            enabled: true,
196            algorithm: DenoisingAlgorithm::NonLocalMeans,
197            strength: 0.8,
198            preserve_edges: true,
199            preserve_details: false,
200            custom_params: HashMap::new(),
201        }
202    }
203
204    /// Create basic noise reduction configuration
205    #[must_use]
206    pub fn basic() -> Self {
207        Self {
208            enabled: true,
209            algorithm: DenoisingAlgorithm::GaussianBlur,
210            strength: 0.3,
211            preserve_edges: false,
212            preserve_details: true,
213            custom_params: HashMap::new(),
214        }
215    }
216}
217
218/// Denoising algorithms
219#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
220pub enum DenoisingAlgorithm {
221    /// Gaussian blur denoising
222    GaussianBlur,
223    /// Bilateral filter
224    BilateralFilter,
225    /// Non-local means denoising
226    NonLocalMeans,
227    /// Wiener filter
228    WienerFilter,
229    /// Wavelet denoising
230    Wavelet,
231    /// Deep learning denoising
232    DeepLearning,
233    /// Custom denoising
234    Custom,
235}
236
237impl Default for DenoisingAlgorithm {
238    fn default() -> Self {
239        Self::BilateralFilter
240    }
241}
242
243/// Sharpening configuration
244#[derive(Debug, Clone, Serialize, Deserialize)]
245pub struct SharpeningConfig {
246    /// Enable sharpening
247    pub enabled: bool,
248    /// Sharpening strength (0.0-2.0)
249    pub strength: f64,
250    /// Sharpening radius
251    pub radius: f64,
252    /// Threshold for edge detection
253    pub threshold: f64,
254    /// Unsharp mask settings
255    pub unsharp_mask: bool,
256    /// Custom sharpening parameters
257    pub custom_params: HashMap<String, TransformParameter>,
258}
259
260impl Default for SharpeningConfig {
261    fn default() -> Self {
262        Self {
263            enabled: false,
264            strength: 1.0,
265            radius: 1.0,
266            threshold: 0.1,
267            unsharp_mask: true,
268            custom_params: HashMap::new(),
269        }
270    }
271}
272
273impl SharpeningConfig {
274    /// Create enhanced sharpening configuration
275    #[must_use]
276    pub fn enhanced() -> Self {
277        Self {
278            enabled: true,
279            strength: 1.5,
280            radius: 1.5,
281            threshold: 0.05,
282            unsharp_mask: true,
283            custom_params: HashMap::new(),
284        }
285    }
286
287    /// Create minimal sharpening configuration
288    #[must_use]
289    pub fn minimal() -> Self {
290        Self {
291            enabled: true,
292            strength: 0.5,
293            radius: 0.5,
294            threshold: 0.2,
295            unsharp_mask: false,
296            custom_params: HashMap::new(),
297        }
298    }
299}
300
301/// Color correction configuration
302#[derive(Debug, Clone, Serialize, Deserialize)]
303pub struct ColorCorrectionConfig {
304    /// Enable color correction
305    pub enabled: bool,
306    /// Brightness adjustment (-1.0 to 1.0)
307    pub brightness: f64,
308    /// Contrast adjustment (0.0 to 2.0)
309    pub contrast: f64,
310    /// Saturation adjustment (0.0 to 2.0)
311    pub saturation: f64,
312    /// Hue adjustment (-180 to 180 degrees)
313    pub hue: f64,
314    /// Gamma correction (0.1 to 3.0)
315    pub gamma: f64,
316    /// White balance correction
317    pub white_balance: WhiteBalanceConfig,
318    /// Color temperature adjustment
319    pub color_temperature: Option<f64>,
320}
321
322impl Default for ColorCorrectionConfig {
323    fn default() -> Self {
324        Self {
325            enabled: false,
326            brightness: 0.0,
327            contrast: 1.0,
328            saturation: 1.0,
329            hue: 0.0,
330            gamma: 1.0,
331            white_balance: WhiteBalanceConfig::default(),
332            color_temperature: None,
333        }
334    }
335}
336
337impl ColorCorrectionConfig {
338    /// Create accurate color correction configuration
339    #[must_use]
340    pub fn accurate() -> Self {
341        Self {
342            enabled: true,
343            brightness: 0.0,
344            contrast: 1.0,
345            saturation: 1.0,
346            hue: 0.0,
347            gamma: 2.2, // Standard gamma for sRGB
348            white_balance: WhiteBalanceConfig::auto(),
349            color_temperature: Some(6500.0), // Daylight
350        }
351    }
352
353    /// Create basic color correction configuration
354    #[must_use]
355    pub fn basic() -> Self {
356        Self {
357            enabled: true,
358            brightness: 0.0,
359            contrast: 1.0,
360            saturation: 1.0,
361            hue: 0.0,
362            gamma: 1.0,
363            white_balance: WhiteBalanceConfig::none(),
364            color_temperature: None,
365        }
366    }
367}
368
369/// White balance configuration
370#[derive(Debug, Clone, Serialize, Deserialize)]
371pub struct WhiteBalanceConfig {
372    /// Enable white balance correction
373    pub enabled: bool,
374    /// White balance mode
375    pub mode: WhiteBalanceMode,
376    /// Custom white point (R, G, B multipliers)
377    pub custom_white_point: Option<(f64, f64, f64)>,
378}
379
380impl Default for WhiteBalanceConfig {
381    fn default() -> Self {
382        Self {
383            enabled: false,
384            mode: WhiteBalanceMode::Auto,
385            custom_white_point: None,
386        }
387    }
388}
389
390impl WhiteBalanceConfig {
391    /// Create auto white balance configuration
392    #[must_use]
393    pub fn auto() -> Self {
394        Self {
395            enabled: true,
396            mode: WhiteBalanceMode::Auto,
397            custom_white_point: None,
398        }
399    }
400
401    /// Create disabled white balance configuration
402    #[must_use]
403    pub fn none() -> Self {
404        Self {
405            enabled: false,
406            mode: WhiteBalanceMode::None,
407            custom_white_point: None,
408        }
409    }
410}
411
412/// White balance modes
413#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
414pub enum WhiteBalanceMode {
415    /// No white balance correction
416    None,
417    /// Automatic white balance
418    Auto,
419    /// Daylight white balance
420    Daylight,
421    /// Tungsten white balance
422    Tungsten,
423    /// Fluorescent white balance
424    Fluorescent,
425    /// Custom white balance
426    Custom,
427}
428
429/// Quality assurance configuration
430#[derive(Debug, Clone, Serialize, Deserialize)]
431pub struct QualityAssuranceConfig {
432    /// Enable quality checks
433    pub enabled: bool,
434    /// Minimum acceptable quality score
435    pub min_quality_score: f64,
436    /// Maximum acceptable processing time
437    pub max_processing_time: Duration,
438    /// Enable automatic quality adjustment
439    pub auto_adjust: bool,
440    /// Quality metrics to monitor
441    pub monitored_metrics: Vec<String>,
442}
443
444impl Default for QualityAssuranceConfig {
445    fn default() -> Self {
446        Self {
447            enabled: true,
448            min_quality_score: 0.7,
449            max_processing_time: Duration::from_secs(30),
450            auto_adjust: true,
451            monitored_metrics: vec![
452                "sharpness".to_string(),
453                "contrast".to_string(),
454                "brightness".to_string(),
455            ],
456        }
457    }
458}
459
460impl QualityAssuranceConfig {
461    /// Create strict quality assurance configuration
462    #[must_use]
463    pub fn strict() -> Self {
464        Self {
465            enabled: true,
466            min_quality_score: 0.9,
467            max_processing_time: Duration::from_secs(60),
468            auto_adjust: false,
469            monitored_metrics: vec![
470                "sharpness".to_string(),
471                "contrast".to_string(),
472                "brightness".to_string(),
473                "noise_level".to_string(),
474                "color_accuracy".to_string(),
475            ],
476        }
477    }
478
479    /// Create lenient quality assurance configuration
480    #[must_use]
481    pub fn lenient() -> Self {
482        Self {
483            enabled: true,
484            min_quality_score: 0.5,
485            max_processing_time: Duration::from_secs(10),
486            auto_adjust: true,
487            monitored_metrics: vec!["sharpness".to_string()],
488        }
489    }
490}
491
492/// Performance configuration for computer vision processing
493#[derive(Debug, Clone, Serialize, Deserialize)]
494pub struct PerformanceConfig {
495    /// Memory optimization level
496    pub memory_optimization: MemoryOptimizationLevel,
497    /// Caching strategy
498    pub caching: CachingStrategy,
499    /// Parallel processing configuration
500    pub parallel_processing: ParallelProcessingConfig,
501    /// Resource limits
502    pub resource_limits: ResourceLimits,
503    /// Error handling strategy
504    pub error_handling: ErrorHandlingConfig,
505}
506
507impl Default for PerformanceConfig {
508    fn default() -> Self {
509        Self {
510            memory_optimization: MemoryOptimizationLevel::Medium,
511            caching: CachingStrategy::default(),
512            parallel_processing: ParallelProcessingConfig::default(),
513            resource_limits: ResourceLimits::default(),
514            error_handling: ErrorHandlingConfig::default(),
515        }
516    }
517}
518
519/// Caching strategy for performance optimization
520#[derive(Debug, Clone, Serialize, Deserialize)]
521pub struct CachingStrategy {
522    /// Enable caching
523    pub enabled: bool,
524    /// Cache size in bytes
525    pub cache_size: usize,
526    /// Cache eviction policy
527    pub eviction_policy: CacheEvictionPolicy,
528    /// Cache TTL for entries
529    pub ttl: Duration,
530    /// Enable persistent cache
531    pub persistent: bool,
532    /// Cache location
533    pub cache_location: String,
534}
535
536impl Default for CachingStrategy {
537    fn default() -> Self {
538        Self {
539            enabled: true,
540            cache_size: 100 * 1024 * 1024, // 100MB
541            eviction_policy: CacheEvictionPolicy::LRU,
542            ttl: Duration::from_secs(3600), // 1 hour
543            persistent: false,
544            cache_location: "/tmp/cv_cache".to_string(),
545        }
546    }
547}
548
549/// Parallel processing configuration
550#[derive(Debug, Clone, Serialize, Deserialize)]
551pub struct ParallelProcessingConfig {
552    /// Enable parallel processing
553    pub enabled: bool,
554    /// Parallel strategy
555    pub strategy: ParallelStrategy,
556    /// Number of worker threads/processes
557    pub num_workers: usize,
558    /// Load balancing algorithm
559    pub load_balancing: LoadBalancingAlgorithm,
560    /// Batch size for parallel processing
561    pub batch_size: usize,
562    /// Work stealing configuration
563    pub work_stealing: WorkStealingConfig,
564}
565
566impl Default for ParallelProcessingConfig {
567    fn default() -> Self {
568        Self {
569            enabled: true,
570            strategy: ParallelStrategy::Threading,
571            num_workers: num_cpus::get(),
572            load_balancing: LoadBalancingAlgorithm::WorkStealing,
573            batch_size: 32,
574            work_stealing: WorkStealingConfig::default(),
575        }
576    }
577}
578
579/// Work stealing configuration for load balancing
580#[derive(Debug, Clone, Serialize, Deserialize)]
581pub struct WorkStealingConfig {
582    /// Enable work stealing
583    pub enabled: bool,
584    /// Steal threshold (when to steal work)
585    pub steal_threshold: usize,
586    /// Maximum steal attempts
587    pub max_steal_attempts: usize,
588    /// Steal ratio (fraction of work to steal)
589    pub steal_ratio: f64,
590}
591
592impl Default for WorkStealingConfig {
593    fn default() -> Self {
594        Self {
595            enabled: true,
596            steal_threshold: 5,
597            max_steal_attempts: 3,
598            steal_ratio: 0.5,
599        }
600    }
601}
602
603/// Resource limits for processing
604#[derive(Debug, Clone, Serialize, Deserialize)]
605pub struct ResourceLimits {
606    /// Maximum memory usage in bytes
607    pub max_memory: usize,
608    /// Maximum CPU usage percentage
609    pub max_cpu_usage: f64,
610    /// Maximum GPU memory usage in bytes
611    pub max_gpu_memory: Option<usize>,
612    /// Maximum processing time per item
613    pub max_processing_time: Duration,
614    /// Maximum concurrent operations
615    pub max_concurrent_operations: usize,
616}
617
618impl Default for ResourceLimits {
619    fn default() -> Self {
620        Self {
621            max_memory: 1024 * 1024 * 1024, // 1GB
622            max_cpu_usage: 80.0,            // 80%
623            max_gpu_memory: None,
624            max_processing_time: Duration::from_secs(30),
625            max_concurrent_operations: 10,
626        }
627    }
628}
629
630/// Error handling configuration
631#[derive(Debug, Clone, Serialize, Deserialize)]
632pub struct ErrorHandlingConfig {
633    /// Recovery strategy for failures
634    pub recovery_strategy: RecoveryStrategy,
635    /// Maximum retry attempts
636    pub max_retries: usize,
637    /// Retry delay
638    pub retry_delay: Duration,
639    /// Enable graceful degradation
640    pub graceful_degradation: bool,
641    /// Fallback quality level
642    pub fallback_quality: ProcessingComplexity,
643}
644
645impl Default for ErrorHandlingConfig {
646    fn default() -> Self {
647        Self {
648            recovery_strategy: RecoveryStrategy::Skip,
649            max_retries: 3,
650            retry_delay: Duration::from_millis(500),
651            graceful_degradation: true,
652            fallback_quality: ProcessingComplexity::Low,
653        }
654    }
655}
656
657#[allow(non_snake_case)]
658#[cfg(test)]
659mod tests {
660    use super::*;
661
662    #[test]
663    fn test_quality_settings_presets() {
664        let high_quality = QualitySettings::high_quality();
665        assert_eq!(high_quality.quality_level, ProcessingComplexity::High);
666
667        let performance = QualitySettings::performance_optimized();
668        assert_eq!(performance.quality_level, ProcessingComplexity::Low);
669
670        let balanced = QualitySettings::balanced();
671        assert_eq!(balanced.quality_level, ProcessingComplexity::Medium);
672    }
673
674    #[test]
675    fn test_compression_config() {
676        let lossless = CompressionConfig::lossless();
677        assert_eq!(lossless.algorithm, CompressionAlgorithm::PNG);
678        assert_eq!(lossless.quality, 100);
679
680        let fast = CompressionConfig::fast();
681        assert_eq!(fast.algorithm, CompressionAlgorithm::JPEG);
682        assert!(fast.optimize_size);
683    }
684
685    #[test]
686    fn test_noise_reduction_config() {
687        let aggressive = NoiseReductionConfig::aggressive();
688        assert_eq!(aggressive.algorithm, DenoisingAlgorithm::NonLocalMeans);
689        assert_eq!(aggressive.strength, 0.8);
690
691        let basic = NoiseReductionConfig::basic();
692        assert_eq!(basic.algorithm, DenoisingAlgorithm::GaussianBlur);
693        assert_eq!(basic.strength, 0.3);
694    }
695
696    #[test]
697    fn test_color_correction_config() {
698        let accurate = ColorCorrectionConfig::accurate();
699        assert!(accurate.enabled);
700        assert_eq!(accurate.gamma, 2.2);
701        assert_eq!(accurate.color_temperature, Some(6500.0));
702
703        let basic = ColorCorrectionConfig::basic();
704        assert!(basic.enabled);
705        assert_eq!(basic.gamma, 1.0);
706        assert_eq!(basic.color_temperature, None);
707    }
708
709    #[test]
710    fn test_quality_assurance_config() {
711        let strict = QualityAssuranceConfig::strict();
712        assert_eq!(strict.min_quality_score, 0.9);
713        assert!(!strict.auto_adjust);
714        assert_eq!(strict.monitored_metrics.len(), 5);
715
716        let lenient = QualityAssuranceConfig::lenient();
717        assert_eq!(lenient.min_quality_score, 0.5);
718        assert!(lenient.auto_adjust);
719        assert_eq!(lenient.monitored_metrics.len(), 1);
720    }
721
722    #[test]
723    fn test_performance_config_defaults() {
724        let config = PerformanceConfig::default();
725        assert_eq!(config.memory_optimization, MemoryOptimizationLevel::Medium);
726        assert!(config.caching.enabled);
727        assert!(config.parallel_processing.enabled);
728    }
729
730    #[test]
731    fn test_resource_limits() {
732        let limits = ResourceLimits::default();
733        assert_eq!(limits.max_memory, 1024 * 1024 * 1024);
734        assert_eq!(limits.max_cpu_usage, 80.0);
735        assert_eq!(limits.max_concurrent_operations, 10);
736    }
737
738    #[test]
739    fn test_error_handling_config() {
740        let config = ErrorHandlingConfig::default();
741        assert_eq!(config.recovery_strategy, RecoveryStrategy::Skip);
742        assert_eq!(config.max_retries, 3);
743        assert!(config.graceful_degradation);
744        assert_eq!(config.fallback_quality, ProcessingComplexity::Low);
745    }
746}