diff --git a/src/software/scaling/color_space.rs b/src/software/scaling/color_space.rs index 0c741488..f4b01491 100644 --- a/src/software/scaling/color_space.rs +++ b/src/software/scaling/color_space.rs @@ -11,6 +11,7 @@ pub enum ColorSpace { ITU624, SMPTE170M, SMPTE240M, + BT2020, } impl From for ColorSpace { @@ -18,9 +19,10 @@ impl From for ColorSpace { match value { SWS_CS_ITU709 => ColorSpace::ITU709, SWS_CS_FCC => ColorSpace::FCC, + // Default is same as ITU601 SWS_CS_DEFAULT => ColorSpace::Default, SWS_CS_SMPTE240M => ColorSpace::SMPTE240M, - + SWS_CS_BT2020 => ColorSpace::BT2020, _ => ColorSpace::Default, } } @@ -36,6 +38,7 @@ impl From for c_int { ColorSpace::ITU624 => SWS_CS_ITU624, ColorSpace::SMPTE170M => SWS_CS_SMPTE170M, ColorSpace::SMPTE240M => SWS_CS_SMPTE240M, + ColorSpace::BT2020 => SWS_CS_BT2020, } } } diff --git a/src/software/scaling/context.rs b/src/software/scaling/context.rs index 0469a23e..0c7788d5 100644 --- a/src/software/scaling/context.rs +++ b/src/software/scaling/context.rs @@ -1,6 +1,8 @@ use std::ptr; -use super::Flags; +use crate::color; + +use super::{ColorSpace, Flags}; use ffi::*; use libc::c_int; use util::format; @@ -78,6 +80,54 @@ impl Context { } } + pub fn set_colorspace_details( + &mut self, + input_space: color::Space, + src_range: color::Range, + dst_range: color::Range, + brightness: i32, + contrast: i32, + saturation: i32, + ) -> Result<(), Error> { + unsafe { + let input_color_space_int = match input_space { + color::Space::BT709 => ColorSpace::ITU709, + color::Space::BT2020CL => ColorSpace::BT2020, + color::Space::BT2020NCL => ColorSpace::BT2020, + _ => ColorSpace::ITU601, + }; + let coefficients: *const i32 = sws_getCoefficients(input_color_space_int.into()); + + // 0 means limited range (16-235), 1 means full range (0-255) + let src_range_value = match src_range { + color::Range::MPEG => 0, + color::Range::JPEG => 1, + color::Range::Unspecified => 1, + }; + // 0 means limited range, 1 means full range + // For an RGB image, we want full range, for YUV, most of the time we want limited range + let dst_range_value = match dst_range { + color::Range::MPEG => 0, + color::Range::JPEG => 1, + color::Range::Unspecified => 1, + }; + + match sws_setColorspaceDetails( + self.as_mut_ptr(), + coefficients, + src_range_value, + coefficients, + dst_range_value, + brightness, + contrast, + saturation, + ) { + e if e < 0 => Err(Error::from(e)), + _ => Ok(()), + } + } + } + pub fn cached( &mut self, src_format: format::Pixel,