| // Copyright 2024 Google LLC |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| use crate::*; |
| |
| fn expand_coeffs(y: f32, v: f32) -> [f32; 3] { |
| [y, 1.0 - y - v, v] |
| } |
| |
| impl ColorPrimaries { |
| pub(crate) fn y_coeffs(&self) -> [f32; 3] { |
| // These values come from computations in Section 8 of |
| // https://www.itu.int/rec/T-REC-H.273-201612-S |
| match self { |
| ColorPrimaries::Unknown | ColorPrimaries::Srgb | ColorPrimaries::Unspecified => { |
| expand_coeffs(0.2126, 0.0722) |
| } |
| ColorPrimaries::Bt470m => expand_coeffs(0.299, 0.1146), |
| ColorPrimaries::Bt470bg => expand_coeffs(0.222, 0.0713), |
| ColorPrimaries::Bt601 | ColorPrimaries::Smpte240 => expand_coeffs(0.212, 0.087), |
| ColorPrimaries::GenericFilm => expand_coeffs(0.2536, 0.06808), |
| ColorPrimaries::Bt2020 => expand_coeffs(0.2627, 0.0593), |
| ColorPrimaries::Xyz => expand_coeffs(0.0, 0.0), |
| ColorPrimaries::Smpte431 => expand_coeffs(0.2095, 0.0689), |
| ColorPrimaries::Smpte432 => expand_coeffs(0.229, 0.0793), |
| ColorPrimaries::Ebu3213 => expand_coeffs(0.2318, 0.096), |
| } |
| } |
| } |
| |
| fn calculate_yuv_coefficients_from_cicp( |
| color_primaries: ColorPrimaries, |
| matrix_coefficients: MatrixCoefficients, |
| ) -> Option<[f32; 3]> { |
| match matrix_coefficients { |
| MatrixCoefficients::ChromaDerivedNcl => Some(color_primaries.y_coeffs()), |
| MatrixCoefficients::Bt709 => Some(expand_coeffs(0.2126, 0.0722)), |
| MatrixCoefficients::Fcc => Some(expand_coeffs(0.30, 0.11)), |
| MatrixCoefficients::Bt470bg | MatrixCoefficients::Bt601 => { |
| Some(expand_coeffs(0.299, 0.114)) |
| } |
| MatrixCoefficients::Smpte240 => Some(expand_coeffs(0.212, 0.087)), |
| MatrixCoefficients::Bt2020Ncl => Some(expand_coeffs(0.2627, 0.0593)), |
| _ => None, |
| } |
| } |
| |
| pub(crate) fn calculate_yuv_coefficients( |
| color_primaries: ColorPrimaries, |
| matrix_coefficients: MatrixCoefficients, |
| ) -> [f32; 3] { |
| // Return known coefficients or fall back to BT.601. |
| calculate_yuv_coefficients_from_cicp(color_primaries, matrix_coefficients).unwrap_or( |
| calculate_yuv_coefficients_from_cicp(color_primaries, MatrixCoefficients::Bt601).unwrap(), |
| ) |
| } |
| |
| #[cfg(test)] |
| mod tests { |
| use super::*; |
| use crate::internal_utils::assert_eq_f32_array; |
| |
| #[test] |
| fn yuv_coefficients() { |
| assert_eq_f32_array( |
| &calculate_yuv_coefficients(ColorPrimaries::Unknown, MatrixCoefficients::Bt601), |
| &[0.299f32, 0.587f32, 0.114f32], // Kr,Kg,Kb as https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.601_conversion |
| ); |
| assert_eq_f32_array( |
| &calculate_yuv_coefficients(ColorPrimaries::Unknown, MatrixCoefficients::Unspecified), |
| &[0.299f32, 0.587f32, 0.114f32], // Falls back to Bt601. |
| ); |
| assert_eq_f32_array( |
| &calculate_yuv_coefficients(ColorPrimaries::Unknown, MatrixCoefficients::Smpte240), |
| &[0.212f32, 1f32 - 0.212 - 0.087, 0.087f32], // Kr,Kg,Kb as https://en.wikipedia.org/wiki/YCbCr#SMPTE_240M_conversion |
| ); |
| } |
| } |