diff --git a/libavutil/csp.c b/libavutil/csp.c index 7ebbcc5856..5f37984429 100644 --- a/libavutil/csp.c +++ b/libavutil/csp.c @@ -537,6 +537,7 @@ static void oetf_##name##_inv(double E[3]) \ WRAP_SDR_OETF(gamma22) WRAP_SDR_OETF(gamma28) WRAP_SDR_OETF(iec61966_2_1) +WRAP_SDR_OETF(smpte_st428_1) #define WRAP_SDR_EOTF(name) \ static void eotf_##name(double Lw, double Lb, double E[3]) \ @@ -554,6 +555,7 @@ static void eotf_##name##_inv(double Lw, double Lb, double L[3]) \ WRAP_SDR_EOTF(gamma22) WRAP_SDR_EOTF(gamma28) WRAP_SDR_EOTF(iec61966_2_1) +WRAP_SDR_EOTF(smpte_st428_1) static void eotf_bt1886(const double Lw, const double Lb, double E[3]) { @@ -589,34 +591,6 @@ static void eotf_smpte_st2084_inv(const double Lw, const double Lb, double L[3]) L[i] = trc_smpte_st2084(L[i]); } -/* This implementation assumes an SMPTE RP 431-2 reference projector (DCI) */ -#define DCI_L 48.00 -#define DCI_P 52.37 -#define DCI_X (42.94 / DCI_L) -#define DCI_Z (45.82 / DCI_L) - -static void eotf_smpte_st428_1(const double Lw_Y, const double Lb_Y, double E[3]) -{ - const double Lw[3] = { DCI_X * Lw_Y, Lw_Y, DCI_Z * Lw_Y }; - const double Lb[3] = { DCI_X * Lb_Y, Lb_Y, DCI_Z * Lb_Y }; - - for (int i = 0; i < 3; i++) { - E[i] = (0.0 > E[i]) ? 0.0 : pow(E[i], 2.6) * DCI_P / DCI_L; - E[i] = E[i] * (Lw[i] - Lb[i]) + Lb[i]; - } -} - -static void eotf_smpte_st428_1_inv(const double Lw_Y, const double Lb_Y, double L[3]) -{ - const double Lw[3] = { DCI_X * Lw_Y, Lw_Y, DCI_Z * Lw_Y }; - const double Lb[3] = { DCI_X * Lb_Y, Lb_Y, DCI_Z * Lb_Y }; - - for (int i = 0; i < 3; i++) { - L[i] = (L[i] - Lb[i]) / (Lw[i] - Lb[i]); - L[i] = (0.0 > L[i]) ? 0.0 : pow(L[i] * DCI_L / DCI_P, 1.0 / 2.6); - } -} - static void eotf_arib_std_b67(const double Lw, const double Lb, double E[3]) { const double gamma = fmax(1.2 + 0.42 * log10(Lw / 1000.0), 1.0); diff --git a/libavutil/csp.h b/libavutil/csp.h index 9d75ccbb64..8c035b4686 100644 --- a/libavutil/csp.h +++ b/libavutil/csp.h @@ -180,8 +180,9 @@ typedef void (*av_csp_eotf_function)(double Lw, double Lb, double c[3]); /** * Returns the ITU EOTF corresponding to a given TRC. This converts from the * signal level [0,1] to the raw output display luminance in nits (cd/m^2). - * This is done per channel in RGB space, except for AVCOL_TRC_SMPTE428, which - * assumes CIE XYZ in- and output. + * This is done per channel in RGB space. For X'Y'Z' with AVCOL_TRC_SMPTE428, + * pass Lb = 0 and apply the black level after the conversion to RGB for correct + * white point scaling. * * @return A pointer to the function implementing the given TRC, or NULL if no * such function is defined. diff --git a/tests/ref/fate/color_utils b/tests/ref/fate/color_utils index e681ef7310..237c9ac40f 100644 --- a/tests/ref/fate/color_utils +++ b/tests/ref/fate/color_utils @@ -2741,16 +2741,16 @@ trc=bt2020-12 EOTF(10000, 1.5, {0.7}) = {4360.83} trc=bt2020-12 EOTF(10000, 1.5, {0.8}) = {5943.5} trc=bt2020-12 EOTF(10000, 1.5, {0.9}) = {7818.66} trc=bt2020-12 EOTF(10000, 1.5, {1}) = {10000} -trc=smpte428 EOTF(48.024, 0.024012, {0.0925519, 0.0967033, 0.0949939}) = {0.11771, 0.144579 0.132798}, expected Y=0.140000 -trc=smpte428 EOTF(48.024, 0.024012, {0.185348, 0.193407, 0.189988}) = {0.606907, 0.754996 0.689089}, expected Y=0.750000 -trc=smpte428 EOTF(48.024, 0.024012, {0.2779, 0.29011, 0.284982}) = {1.69956, 2.12172 1.93462}, expected Y=2.120000 -trc=smpte428 EOTF(48.024, 0.024012, {0.370696, 0.386813, 0.379976}) = {3.57084, 4.45587 4.0618}, expected Y=4.450000 -trc=smpte428 EOTF(48.024, 0.024012, {0.463248, 0.483516, 0.474969}) = {6.35753, 7.94085 7.23777}, expected Y=7.940000 -trc=smpte428 EOTF(48.024, 0.024012, {0.5558, 0.58022, 0.569963}) = {10.1955, 12.7421 11.6133}, expected Y=12.740000 -trc=smpte428 EOTF(48.024, 0.024012, {0.648596, 0.676923, 0.664957}) = {15.2212, 19.0123 17.3275}, expected Y=19.010000 -trc=smpte428 EOTF(48.024, 0.024012, {0.741148, 0.773626, 0.759951}) = {21.5223, 26.8938 24.5101}, expected Y=26.890000 -trc=smpte428 EOTF(48.024, 0.024012, {0.833944, 0.87033, 0.854945}) = {29.2401, 36.5213 33.284}, expected Y=36.520000 -trc=smpte428 EOTF(48.024, 0.024012, {0.926496, 0.967033, 0.949939}) = {38.4361, 48.0228 43.7656}, expected Y=48.020000 +trc=smpte428 EOTF(48.024, 0.024012, {0.0925519, 0.0967033, 0.0949939}) = {0.13158, 0.144579 0.139116}, expected Y=0.140000 +trc=smpte428 EOTF(48.024, 0.024012, {0.185348, 0.193407, 0.189988}) = {0.678424, 0.754996 0.721874}, expected Y=0.750000 +trc=smpte428 EOTF(48.024, 0.024012, {0.2779, 0.29011, 0.284982}) = {1.89984, 2.12172 2.02667}, expected Y=2.120000 +trc=smpte428 EOTF(48.024, 0.024012, {0.370696, 0.386813, 0.379976}) = {3.99162, 4.45587 4.25505}, expected Y=4.450000 +trc=smpte428 EOTF(48.024, 0.024012, {0.463248, 0.483516, 0.474969}) = {7.10669, 7.94085 7.58213}, expected Y=7.940000 +trc=smpte428 EOTF(48.024, 0.024012, {0.5558, 0.58022, 0.569963}) = {11.3969, 12.7421 12.1659}, expected Y=12.740000 +trc=smpte428 EOTF(48.024, 0.024012, {0.648596, 0.676923, 0.664957}) = {17.0149, 19.0123 18.1519}, expected Y=19.010000 +trc=smpte428 EOTF(48.024, 0.024012, {0.741148, 0.773626, 0.759951}) = {24.0585, 26.8938 25.6763}, expected Y=26.890000 +trc=smpte428 EOTF(48.024, 0.024012, {0.833944, 0.87033, 0.854945}) = {32.6857, 36.5213 34.8675}, expected Y=36.520000 +trc=smpte428 EOTF(48.024, 0.024012, {0.926496, 0.967033, 0.949939}) = {42.9653, 48.0228 45.8478}, expected Y=48.020000 trc=arib-std-b67 EOTF(50, 0, {0}) = {0} trc=arib-std-b67 EOTF(50, 0, {0.1}) = {0.166667} trc=arib-std-b67 EOTF(50, 0, {0.2}) = {0.666667}