use super::{lut::LutProcessor, match_color::ColorMatcher};
use crate::Result;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ColorPipelineConfig {
pub color_matching: bool,
pub lut_enabled: bool,
pub input_color_space: String,
pub output_color_space: String,
}
impl Default for ColorPipelineConfig {
fn default() -> Self {
Self {
color_matching: true,
lut_enabled: false,
input_color_space: "Rec709".to_string(),
output_color_space: "Rec709".to_string(),
}
}
}
pub struct ColorPipeline {
config: ColorPipelineConfig,
color_matcher: Option<ColorMatcher>,
lut_processor: Option<LutProcessor>,
}
impl ColorPipeline {
pub fn new(config: ColorPipelineConfig) -> Result<Self> {
let color_matcher = if config.color_matching {
Some(ColorMatcher::new()?)
} else {
None
};
let lut_processor = if config.lut_enabled {
Some(LutProcessor::new()?)
} else {
None
};
Ok(Self {
config,
color_matcher,
lut_processor,
})
}
pub fn process(&mut self, frame: &[u8], width: usize, height: usize) -> Result<Vec<u8>> {
let mut output = frame.to_vec();
if let Some(matcher) = &mut self.color_matcher {
output = matcher.process(&output, width, height)?;
}
if let Some(lut) = &mut self.lut_processor {
output = lut.apply(&output, width, height)?;
}
Ok(output)
}
#[must_use]
pub fn config(&self) -> &ColorPipelineConfig {
&self.config
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_color_pipeline() {
let config = ColorPipelineConfig::default();
let pipeline = ColorPipeline::new(config);
assert!(pipeline.is_ok());
}
}