Skip to main content

oxihuman_viewer/
test_pattern_view.rs

1// Copyright (C) 2026 COOLJAPAN OU (Team KitaSan)
2// SPDX-License-Identifier: Apache-2.0
3#![allow(dead_code)]
4
5//! Test pattern (color bars) view for display calibration.
6
7/// Test pattern type.
8#[derive(Debug, Clone, Copy, PartialEq)]
9pub enum TestPatternType {
10    ColorBars,
11    Smpte75,
12    Smpte100,
13    Grayscale,
14    CheckerBoard,
15    SolidColor,
16}
17
18/// Test pattern view configuration.
19#[derive(Debug, Clone)]
20pub struct TestPatternView {
21    pub pattern: TestPatternType,
22    pub grid_size: u32,
23    pub enabled: bool,
24    pub solid_color: [f32; 4],
25}
26
27impl TestPatternView {
28    pub fn new() -> Self {
29        Self {
30            pattern: TestPatternType::ColorBars,
31            grid_size: 8,
32            enabled: false,
33            solid_color: [1.0, 0.0, 0.0, 1.0],
34        }
35    }
36}
37
38impl Default for TestPatternView {
39    fn default() -> Self {
40        Self::new()
41    }
42}
43
44/// Create a new test pattern view.
45pub fn new_test_pattern_view() -> TestPatternView {
46    TestPatternView::new()
47}
48
49/// Set test pattern type.
50pub fn tpv_set_pattern(view: &mut TestPatternView, pattern: TestPatternType) {
51    view.pattern = pattern;
52}
53
54/// Set grid size for checker/grid patterns.
55pub fn tpv_set_grid_size(view: &mut TestPatternView, size: u32) {
56    view.grid_size = size.clamp(2, 256);
57}
58
59/// Enable or disable the test pattern overlay.
60pub fn tpv_set_enabled(view: &mut TestPatternView, enabled: bool) {
61    view.enabled = enabled;
62}
63
64/// Set solid color for SolidColor pattern type.
65pub fn tpv_set_solid_color(view: &mut TestPatternView, r: f32, g: f32, b: f32, a: f32) {
66    view.solid_color = [
67        r.clamp(0.0, 1.0),
68        g.clamp(0.0, 1.0),
69        b.clamp(0.0, 1.0),
70        a.clamp(0.0, 1.0),
71    ];
72}
73
74/// Compute number of color bands for bar patterns.
75pub fn tpv_bar_count(view: &TestPatternView) -> u32 {
76    match view.pattern {
77        TestPatternType::ColorBars | TestPatternType::Smpte75 | TestPatternType::Smpte100 => 7,
78        TestPatternType::Grayscale => 10,
79        TestPatternType::CheckerBoard => view.grid_size * view.grid_size,
80        TestPatternType::SolidColor => 1,
81    }
82}
83
84/// Serialize to JSON-like string.
85pub fn test_pattern_view_to_json(view: &TestPatternView) -> String {
86    let pattern_str = match view.pattern {
87        TestPatternType::ColorBars => "color_bars",
88        TestPatternType::Smpte75 => "smpte_75",
89        TestPatternType::Smpte100 => "smpte_100",
90        TestPatternType::Grayscale => "grayscale",
91        TestPatternType::CheckerBoard => "checker",
92        TestPatternType::SolidColor => "solid",
93    };
94    format!(
95        r#"{{"pattern":"{pattern_str}","grid_size":{},"enabled":{}}}"#,
96        view.grid_size, view.enabled
97    )
98}
99
100#[cfg(test)]
101mod tests {
102    use super::*;
103
104    #[test]
105    fn test_defaults() {
106        let v = new_test_pattern_view();
107        assert_eq!(v.pattern, TestPatternType::ColorBars);
108        assert!(!v.enabled);
109    }
110
111    #[test]
112    fn test_set_pattern() {
113        let mut v = new_test_pattern_view();
114        tpv_set_pattern(&mut v, TestPatternType::Grayscale);
115        assert_eq!(v.pattern, TestPatternType::Grayscale);
116    }
117
118    #[test]
119    fn test_grid_size_clamp() {
120        let mut v = new_test_pattern_view();
121        tpv_set_grid_size(&mut v, 1);
122        assert_eq!(v.grid_size, 2);
123    }
124
125    #[test]
126    fn test_enabled_toggle() {
127        let mut v = new_test_pattern_view();
128        tpv_set_enabled(&mut v, true);
129        assert!(v.enabled);
130    }
131
132    #[test]
133    fn test_bar_count_color_bars() {
134        let v = new_test_pattern_view();
135        assert_eq!(tpv_bar_count(&v), 7);
136    }
137
138    #[test]
139    fn test_bar_count_grayscale() {
140        let mut v = new_test_pattern_view();
141        tpv_set_pattern(&mut v, TestPatternType::Grayscale);
142        assert_eq!(tpv_bar_count(&v), 10);
143    }
144
145    #[test]
146    fn test_solid_color_set() {
147        let mut v = new_test_pattern_view();
148        tpv_set_solid_color(&mut v, 0.0, 1.0, 0.0, 1.0);
149        assert!((v.solid_color[1] - 1.0).abs() < 1e-6);
150    }
151
152    #[test]
153    fn test_json() {
154        let v = new_test_pattern_view();
155        let s = test_pattern_view_to_json(&v);
156        assert!(s.contains("color_bars"));
157    }
158
159    #[test]
160    fn test_clone() {
161        let v = new_test_pattern_view();
162        let v2 = v.clone();
163        assert_eq!(v2.pattern, v.pattern);
164    }
165}