diff --git a/src/color.c b/src/color.c index e5ec1a03a..baf4e10d3 100644 --- a/src/color.c +++ b/src/color.c @@ -42,53 +42,63 @@ #include "types.h" // for depth -#define KG_709 KG(KR_709,KB_709) -#define D (2.*(KR_709+KG_709)) -#define E (2.*(1.-KR_709)) +#define D(kr, kb) (2. * ((kr) + KG(kr, kb))) +#define E(kr) (2. * (1. - (kr))) -#define Y_R(out_depth) \ - ((comp_type_t) (((KR_709 * Y_LIMIT(out_depth)) * (1 << COMP_BASE)) + \ +#define Y_R(out_depth, kr, kb) \ + ((comp_type_t) (((kr * Y_LIMIT(out_depth)) * (1 << COMP_BASE)) + C_EPS)) +#define Y_G(out_depth, kr, kb) \ + ((comp_type_t) (((KG(kr, kb) * Y_LIMIT(out_depth)) * \ + (1 << COMP_BASE)) + \ C_EPS)) -#define Y_G(out_depth) \ - ((comp_type_t) (((KG_709 * Y_LIMIT(out_depth)) * (1 << COMP_BASE)) + \ +#define Y_B(out_depth, kr, kb) \ + ((comp_type_t) ((((kb) * Y_LIMIT(out_depth)) * (1 << COMP_BASE)) + \ C_EPS)) -#define Y_B(out_depth) \ - ((comp_type_t) (((KB_709 * Y_LIMIT(out_depth)) * (1 << COMP_BASE)) + \ +#define CB_R(out_depth, kr, kb) \ + ((comp_type_t) (((-(kr) / D(kr, kb) * CBCR_LIMIT(out_depth)) * \ + (1 << COMP_BASE)) - \ + C_EPS)) +#define CB_G(out_depth, kr, kb) \ + ((comp_type_t) (((-KG(kr, kb) / D(kr, kb) * CBCR_LIMIT(out_depth)) * \ + (1 << COMP_BASE)) - \ + C_EPS)) +#define CB_B(out_depth, kr, kb) \ + ((comp_type_t) ((((1 - (kb)) / D(kr, kb) * CBCR_LIMIT(out_depth)) * \ + (1 << COMP_BASE)) + \ + C_EPS)) +#define CR_R(out_depth, kr, kb) \ + ((comp_type_t) ((((1 - (kr)) / E(kr) * CBCR_LIMIT(out_depth)) * \ + (1 << COMP_BASE)) - \ + C_EPS)) +#define CR_G(out_depth, kr, kb) \ + ((comp_type_t) (((-KG(kr, kb) / E(kr) * CBCR_LIMIT(out_depth)) * \ + (1 << COMP_BASE)) - \ + C_EPS)) +#define CR_B(out_depth, kr, kb) \ + ((comp_type_t) (((-(kb) / E(kr) * CBCR_LIMIT(out_depth)) * \ + (1 << COMP_BASE)) + \ C_EPS)) -#define CB_R(out_depth) \ - ((comp_type_t) (((-KR_709 / D * CBCR_LIMIT(out_depth)) * \ - (1 << COMP_BASE)) - C_EPS)) -#define CB_G(out_depth) \ - ((comp_type_t) (((-KG_709 / D * CBCR_LIMIT(out_depth)) * \ - (1 << COMP_BASE)) - C_EPS)) -#define CB_B(out_depth) \ - ((comp_type_t) ((((1 - KB_709) / D * CBCR_LIMIT(out_depth)) * \ - (1 << COMP_BASE)) + C_EPS)) -#define CR_R(out_depth) \ - ((comp_type_t) ((((1 - KR_709) / E * CBCR_LIMIT(out_depth)) * \ - (1 << COMP_BASE)) - C_EPS)) -#define CR_G(out_depth) \ - ((comp_type_t) (((-KG_709 / E * CBCR_LIMIT(out_depth)) * \ - (1 << COMP_BASE)) - C_EPS)) -#define CR_B(out_depth) \ - ((comp_type_t) (((-KB_709 / E * CBCR_LIMIT(out_depth)) * \ - (1 << COMP_BASE)) + C_EPS)) -#define COEFFS(depth) \ +#define COEFFS(depth, kr, kb) \ { \ - Y_R(depth), Y_G(depth), Y_B(depth),\ - CB_R(depth), CB_G(depth), CB_B(depth),\ - CR_R(depth), CR_G(depth), CR_B(depth),\ + Y_R(depth, kr, kb), Y_G(depth, kr, kb), Y_B(depth, kr, kb),\ + CB_R(depth, kr, kb), CB_G(depth, kr, kb), CB_B(depth, kr, kb),\ + CR_R(depth, kr, kb), CR_G(depth, kr, kb), CR_B(depth, kr, kb),\ \ - SCALED(R_CR(depth, KR_709, KB_709)), \ - SCALED(G_CB(depth, KR_709, KB_709)), \ - SCALED(G_CR(depth, KR_709, KB_709)), \ - SCALED(B_CB(depth, KR_709, KB_709)), \ + SCALED(R_CR(depth, kr, kb)), \ + SCALED(G_CB(depth, kr, kb)), \ + SCALED(G_CR(depth, kr, kb)), \ + SCALED(B_CB(depth, kr, kb)), \ } +#define COEFFS_709(depth) COEFFS(depth, KR_709, KB_709) + /** * @brief returns color coefficient for RGB<-YCbCr conversion * + * Using BT.709 by default. + * + * * @note * It is suggested to copy the result to a struct (not using the returned ptr * directly) when passing to RGB_TO_*() or YCBCR_TO_*(). The compiler may not @@ -99,10 +109,10 @@ const struct color_coeffs * get_color_coeffs(int ycbcr_bit_depth) { - static const struct color_coeffs col_cfs_8 = COEFFS(DEPTH8); - static const struct color_coeffs col_cfs_10 = COEFFS(DEPTH10); - static const struct color_coeffs col_cfs_12 = COEFFS(DEPTH12); - static const struct color_coeffs col_cfs_16 = COEFFS(DEPTH16); + static const struct color_coeffs col_cfs_8 = COEFFS_709(DEPTH8); + static const struct color_coeffs col_cfs_10 = COEFFS_709(DEPTH10); + static const struct color_coeffs col_cfs_12 = COEFFS_709(DEPTH12); + static const struct color_coeffs col_cfs_16 = COEFFS_709(DEPTH16); switch ((enum depth) ycbcr_bit_depth) { case DEPTH8: return &col_cfs_8; diff --git a/src/color.h b/src/color.h index aa4862a93..3afd3a513 100644 --- a/src/color.h +++ b/src/color.h @@ -47,20 +47,25 @@ #include "utils/macros.h" // CLAMP -/* @brief Color space coedfficients - RGB full range to YCbCr bt. 709 limited range +/** + * @file + * @brief Color space coedfficients and limits * - * RGB should use SDI full range [1<<(depth-8)..255<<(depth-8)-1], see [limits] + * RGB should use SDI full range [1<<(depth-8)..255<<(depth-8)-1], YCbCr + * limited, see [limits]. + * + * The coefficients are scaled by 1<= COMP_BASE + 18, "comp_type_t not wide e ((alpha_mask) | (CLAMP_FULL((r), (depth)) << (rshift) | \ CLAMP_FULL((g), (depth)) << (gshift) | \ CLAMP_FULL((b), (depth)) << (bshift))) -/// @} #define MK_MONOCHROME(val) \ FORMAT_RGBA((val), (val), (val), 0, 8, 16, 0xFF000000, 8)