diff options
Diffstat (limited to '')
-rw-r--r-- | src/libclut.h | 570 |
1 files changed, 558 insertions, 12 deletions
diff --git a/src/libclut.h b/src/libclut.h index 9bc1876..e1601f1 100644 --- a/src/libclut.h +++ b/src/libclut.h @@ -224,6 +224,38 @@ /** * Initialiser for `struct libclut_rgb_colour_space` with the values + * of the ITU-R Recommendation BT.709 (ITU-R BT.709) colour space. + * + * This gamma colour space's gamma is 2.4. It cannot be used with + * RGB colour space conversion unless the values are tranlated into + * using the sRGB gamma function. + */ +#define LIBCLUT_RGB_COLOUR_SPACE_ITU_R_BT_709_INITIALISER \ + { \ + .red_x = 0.6400, .red_y = 0.3300, .red_Y = 0.212656, \ + .green_x = 0.3000, .green_y = 0.6000, .green_Y = 0.715158, \ + .blue_x = 0.1500, .blue_y = 0.0600, .blue_Y = 0.072186, \ + LIBCLUT_ILLUMINANT_D65 \ + } + +/** + * Initialiser for `struct libclut_rgb_colour_space` with the values + * of the Lightroom RGB colour space. + * + * This gamma colour space's gamma is 1.0. It cannot be used with + * RGB colour space conversion unless the values are tranlated into + * using the sRGB gamma function. + */ +#define LIBCLUT_RGB_COLOUR_SPACE_LIGHTROOM_RGB_INITIALISER \ + { \ + .red_x = 0.7347, .red_y = 0.2653, .red_Y = 0.288040, \ + .green_x = 0.1596, .green_y = 0.8404, .green_Y = 0.711874, \ + .blue_x = 0.0366, .blue_y = 0.0001, .blue_Y = 0.000086, \ + LIBCLUT_ILLUMINANT_D50 \ + } + +/** + * Initialiser for `struct libclut_rgb_colour_space` with the values * of the NTSC RGB colour space. * * This gamma colour space's gamma is 2.2. It cannot be used with @@ -302,6 +334,18 @@ LIBCLUT_ILLUMINANT_D50 \ } +/* + * name gamma xw yw xr yr xg yg xb yb + * ITU-R Recommendation BT.2020 (ITU-R BT.2020) *1 { D65 } 0.708 0.292 0.170 0.797 0.131 0.046 + * ITU-R Recommendation BT.2100 (ITU-R BT.2100) *2 { D65 } 0.708 0.292 0.170 0.797 0.131 0.046 + * DCI-P3 D65 ? { D65 } 0.680 0.320 0.265 0.690 0.150 0.060 + * DCI-P3 Theater ? 0.314 0.351 0.680 0.320 0.265 0.690 0.150 0.060 + * https://en.wikipedia.org/wiki/Rec._601 + * + * *1 https://en.wikipedia.org/wiki/Rec._2020#Transfer_characteristics + * *2 http://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.2100-0-201607-I!!PDF-E.pdf + */ + /** @@ -371,6 +415,7 @@ typedef struct libclut_rgb_colour_space } libclut_rgb_colour_space_t; + /** * Matrix date-type for colour space conversion. */ @@ -519,7 +564,7 @@ static inline int libclut_0__(double x) { return libclut_eq__(x, 0); } /** - * Convert the curves from formatted in standard RGB to linear RGB. + * Convert the curves from formatted in standard RGB to linear sRGB. * * None of the parameter may have side-effects. * @@ -551,7 +596,7 @@ static inline int libclut_0__(double x) { return libclut_eq__(x, 0); } /** - * Convert the curves from formatted in linear RGB to standard RGB. + * Convert the curves from formatted in linear sRGB to standard RGB. * * None of the parameter may have side-effects. * @@ -1651,13 +1696,13 @@ static inline int libclut_0__(double x) { return libclut_eq__(x, 0); } /** - * Convert one component from [0, 1] linear RGB to [0, 1] sRGB. + * Convert one component from [0, 1] linear sRGB to [0, 1] sRGB. * * If the macro variant is used, the argument must not have * any side-effects. The macro variant requires linking with * '-lm'. * - * @param c The linear RGB value. + * @param c The linear sRGB value. * @return Corresponding sRGB value. */ LIBCLUT_GCC_ONLY__(__attribute__((__const__, __leaf__))) @@ -1667,7 +1712,7 @@ double (libclut_model_linear_to_standard1)(double); /** - * Convert [0, 1] linear RGB to [0, 1] sRGB. + * Convert [0, 1] linear sRGB to [0, 1] sRGB. * * The macro variant requires linking with '-lm', * if the 'libclut_model_linear_to_standard1' is defined, @@ -1693,14 +1738,14 @@ void (libclut_model_linear_to_standard)(double*, double*, double*); /** - * Convert one component from [0, 1] sRGB to [0, 1] linear RGB. + * Convert one component from [0, 1] sRGB to [0, 1] linear sRGB. * * If the macro variant is used, the argument must not have * any side-effects. The macro variant requires linking with * '-lm'. * * @param c The sRGB value. - * @return Corresponding linear RGB value. + * @return Corresponding linear sRGB value. */ LIBCLUT_GCC_ONLY__(__attribute__((__const__, __leaf__))) double (libclut_model_standard_to_linear1)(double); @@ -1709,7 +1754,7 @@ double (libclut_model_standard_to_linear1)(double); /** - * Convert [0, 1] sRGB to [0, 1] linear RGB. + * Convert [0, 1] sRGB to [0, 1] linear sRGB. * * The macro variant requires linking with '-lm', * if the 'libclut_model_standard_to_linear1' is defined, @@ -1780,7 +1825,7 @@ void (libclut_model_ciexyz_to_ciexyy)(double, double, double, double*, double*); /** - * Convert CIE XYZ to [0, 1] linear RGB. + * Convert CIE XYZ to [0, 1] linear sRGB. * * @param X The X parameter. * @param Y The Y parameter. @@ -1803,7 +1848,7 @@ void (libclut_model_ciexyz_to_linear)(double, double, double, double*, double*, /** - * Convert [0, 1] linear RGB to CIE XYZ. + * Convert [0, 1] linear sRGB to CIE XYZ. * * @param r The red component. * @param g The green component. @@ -1826,7 +1871,7 @@ void (libclut_model_linear_to_ciexyz)(double, double, double, double*, double*, /** - * Convert [0, 1] linear RGB to CIE xyY. + * Convert [0, 1] linear sRGB to CIE xyY. * * The macro variant requires linking with '-lclut' * if any of `libclut_model_ciexyz_to_ciexyy`, @@ -1950,6 +1995,507 @@ void (libclut_model_cielab_to_ciexyz)(double, double, double, double*, double*, /** + * Convert from CIE XYZ to CIELUV. + * + * Requires linking with `-lm`. + * + * @param X The X component. + * @param Y The Y component. + * @param Z The Z component. + * @param Xn The X component of the specified white object (white point). + * @param Yn The Y component of the specified white object (white point). + * @param Zn The Z component of the specified white object (white point). + * @param L Output parameter for the L* parameter. + * @param u Output parameter for the u* parameter. + * @param v Output parameter for the v* parameter. + */ +LIBCLUT_GCC_ONLY__(__attribute__((__leaf__))) +void (libclut_model_ciexyz_to_cieluv)(double, double, double, double, double, + double, double*, double*, double*); +#define libclut_model_ciexyz_to_cieluv(X, Y, Z, Xn, Yn, Zn, L, u, v) \ + do \ + { \ + double x__ = (Xn), y__ = (Yn); \ + double t__ = x__ + 15 * y__ + 3 * (Zn); \ + double u__ = 4 * x__ / t__; \ + double v__ = 9 * y__ / t__; \ + x__ = (X), y__ = (Y); \ + t__ = x__ + 15 * y__ + 3 * (Z); \ + u__ = 4 * x__ / t__ - u__; \ + v__ = 9 * y__ / t__ - v__; \ + y__ = (Y) / y__; \ + if (y__ * 24389 <= (double)216) \ + y__ *= 24389, y__ /= 27; \ + else \ + y__ = cbrt(y__) * 116 - 16; \ + *(L) = y__; \ + y__ *= 13; \ + *(u) = y__ * u__; \ + *(v) = y__ * v__; \ + } \ + while (0) + + +/** + * Convert from CIELUV to CIE XYZ. + * + * @param L The L* component. + * @param u The u* component. + * @param v The v* component. + * @param Xn The X component of the specified white object (white point). + * @param Yn The Y component of the specified white object (white point). + * @param Zn The Z component of the specified white object (white point). + * @param X Output parameter for the X parameter. + * @param Y Output parameter for the Y parameter. + * @param Z Output parameter for the Z parameter. + */ +LIBCLUT_GCC_ONLY__(__attribute__((__leaf__))) +void (libclut_model_cieluv_to_ciexyz)(double, double, double, double, double, + double, double*, double*, double*); +#define libclut_model_cieluv_to_ciexyz(L, u, v, Xn, Yn, Zn, X, Y, Z) \ + do \ + { \ + double x__ = (Xn), y__ = (Yn), l__ = (L), l13__ = l__ * 13; \ + double t__ = x__ + 15 * y__ + 3 * (Zn); \ + double u__ = 4 * x__ / t__; \ + double v__ = 9 * y__ / t__; \ + u__ = (u) / l13__ + u__; \ + v__ = (v) / l13__ + v__; \ + if (l__ <= (double)8) \ + y__ *= l__ * 27 / 24389; \ + else \ + { \ + l__ += 16, l__ /= 116; \ + y__ *= l__ *= l__ * l__; \ + } \ + *(Y) = y__; \ + *(X) = y__ * 9 * u__ / (4 * v__); \ + *(Z) = y__ * (12 - 3 * u__ - 20 * v__) / (4 * v__); \ + } \ + while (0) + + +/** + * Convert from CIELCh to CIE L*u*v*. + * + * Requires linking with `-lm`. + * + * @param C The C*_uv component. + * @param h The h_uv component. + * @param u Output parameter for the u* parameter. + * @param v Output parameter for the v* parameter. + */ +LIBCLUT_GCC_ONLY__(__attribute__((__leaf__))) +void (libclut_model_cielch_to_cieluv)(double, double, double*, double*); +#define libclut_model_cielch_to_cieluv(C, h, u, v) \ + do \ + { \ + double h__ = (h), C__ = (C); \ + *(u) = sin(h__) * C__; \ + *(v) = cos(h__) * C__; \ + } \ + while (0) + + +/** + * Convert from CIE L*u*v* to CIELCh. + * + * Requires linking with `-lm`. + * + * @param u The u* component. + * @param v The v* component. + * @param C Output parameter for the C*_uv parameter. + * @param h Output parameter for the h_uv parameter. + */ +LIBCLUT_GCC_ONLY__(__attribute__((__leaf__))) +void (libclut_model_cieluv_to_cielch)(double, double, double*, double*); +#define libclut_model_cieluv_to_cielch(u, v, C, h) \ + do \ + { \ + double u__ = (u), v__ = (v__); \ + *(C) = sqrt(u__ * u__ + v__ * v__); \ + *(h) = atan2(u__, v__); \ + } \ + while (0) + + +/** + * Convert from sRGB to YIQ. + * + * Requires linking with '-lclut', or '-lm' if + * `libclut_model_standard_to_linear1` is not undefined. + * + * @param r The R component. + * @param g The G component. + * @param b The B component. + * @param y Output parameter for the Y parameter. + * @param i Output parameter for the I parameter. + * @param q Output parameter for the Q parameter. + */ +LIBCLUT_GCC_ONLY__(__attribute__((__leaf__))) +void (libclut_model_srgb_to_yiq)(double, double, double, double*, double*, double*); +#define libclut_model_srgb_to_yiq(r, g, b, y, i, q) \ + do \ + { \ + double r__ = libclut_model_standard_to_linear1(r); \ + double g__ = libclut_model_standard_to_linear1(g); \ + double b__ = libclut_model_standard_to_linear1(b); \ + *(y) = r__ * 299 / 1000 + g__ * 587 / 1000 + b__ * 114 / 1000; \ + *(i) = r__ * 596 / 1000 - g__ * 247 / 1000 - b__ * 322 / 1000; \ + *(q) = r__ * 211 / 1000 - g__ * 523 / 1000 + b__ * 312 / 1000; \ + } \ + while (0) + + +/** + * Convert from YIQ to sRGB. + * + * Requires linking with '-lclut', or '-lm' if + * `libclut_model_linear_to_standard1` is not undefined. + * + * @param y The Y component. + * @param i The I component. + * @param q The Q component. + * @param r Output parameter for the R parameter. + * @param g Output parameter for the G parameter. + * @param b Output parameter for the B parameter. + */ +LIBCLUT_GCC_ONLY__(__attribute__((__leaf__))) +void (libclut_model_yiq_to_srgb)(double, double, double, double*, double*, double*); +#define libclut_model_yiq_to_srgb(y, i, q, r, g, b) \ + do \ + { \ + double y__ = (y), i__ = (i), q__ = (q), r__, g__, b__; \ + r__ = y__ + i__ * 596 / 1000 + q__ * 621 / 1000; \ + g__ = y__ - i__ * 272 / 1000 - q__ * 647 / 1000; \ + b__ = y__ - i__ * 1106 / 1000 + q__ * 1703 / 1000; \ + *(r) = libclut_model_linear_to_standard1(r__); \ + *(g) = libclut_model_linear_to_standard1(g__); \ + *(b) = libclut_model_linear_to_standard1(b__); \ + } \ + while (0) + + +/** + * Convert from sRGB to YDbDr. + * + * Requires linking with '-lclut', or '-lm' if + * `libclut_model_standard_to_linear1` is not undefined. + * + * @param r The R component. + * @param g The G component. + * @param b The B component. + * @param y Output parameter for the Y parameter. + * @param db Output parameter for the Db parameter. + * @param dr Output parameter for the Dr parameter. + */ +LIBCLUT_GCC_ONLY__(__attribute__((__leaf__))) +void (libclut_model_srgb_to_ydbdr)(double, double, double, double*, double*, double*); +#define libclut_model_srgb_to_ydbdr(r, g, b, y, db, dr) \ + do \ + { \ + double r__ = libclut_model_standard_to_linear1(r); \ + double g__ = libclut_model_standard_to_linear1(g); \ + double b__ = libclut_model_standard_to_linear1(b); \ + *(y) = r__ * 299 / 1000 + g__ * 587 / 1000 + b__ * 114 / 1000; \ + *(db) = -r__ * 450 / 1000 - g__ * 883 / 1000 + b__ * 1333 / 1000; \ + *(dr) = -r__ * 1333 / 1000 + g__ * 1116 / 1000 + b__ * 217 / 1000; \ + } \ + while (0) + + +/** + * Convert from YDbDr to sRGB. + * + * Requires linking with '-lclut', or '-lm' if + * `libclut_model_linear_to_standard1` is not undefined. + * + * @param y The Y component. + * @param db The Db component. + * @param dr The Dr component. + * @param r Output parameter for the R parameter. + * @param g Output parameter for the G parameter. + * @param b Output parameter for the B parameter. + */ +LIBCLUT_GCC_ONLY__(__attribute__((__leaf__))) +void (libclut_model_ydbdr_to_srgb)(double, double, double, double*, double*, double*); +#define libclut_model_ydbdr_to_srgb(y, db, dr, r, g, b) \ + do \ + { \ + double y__ = (y), db__ = (db), dr__ = (dr), r__, g__, b__; \ + db__ /= 1000000000000000ULL; \ + dr__ /= 1000000000000000ULL; \ + r__ = y__ + db__ * 92303716148ULL - dr__ * 525912630661865ULL; \ + g__ = y__ - db__ * 129132898890509ULL + dr__ * 267899328207599ULL; \ + b__ = y__ + db__ * 664679059978955ULL - dr__ * 79202543533ULL; \ + *(r) = libclut_model_linear_to_standard1(r__); \ + *(g) = libclut_model_linear_to_standard1(g__); \ + *(b) = libclut_model_linear_to_standard1(b__); \ + } \ + while (0) + + +/** + * Convert from YUV to YDbDr. + * + * @param u The U component. + * @param v The V component. + * @param db Output parameter for the Db parameter. + * @param dr Output parameter for the Dr parameter. + */ +LIBCLUT_GCC_ONLY__(__attribute__((__leaf__))) +void (libclut_model_yuv_to_ydbdr)(double, double, double*, double*); +#define libclut_model_yuv_to_ydbdr(u, v, db, dr) \ + do \ + { \ + *(db) = 3069 * (u) / 1000; \ + *(dr) = -2169 * (v) / 1000; \ + } \ + while (0) + + +/** + * Convert from YDbDr to YUV. + * + * @param db The Db component. + * @param dr The Dr component. + * @param u Output parameter for the U parameter. + * @param v Output parameter for the V parameter. + */ +LIBCLUT_GCC_ONLY__(__attribute__((__leaf__))) +void (libclut_model_ydbdr_to_yuv)(double, double, double*, double*); +#define libclut_model_ydbdr_to_yuv(db, dr, u, v) \ + do \ + { \ + *(u) = (db) * 1000 / 3069; \ + *(v) = (dr) * 1000 / -2169; \ + } \ + while (0) + + +/** + * Convert from sRGB to YPbPr. + * + * Requires linking with '-lclut', or '-lm' if + * `libclut_model_standard_to_linear1` is not undefined. + * + * @param r The R component. + * @param g The G component. + * @param b The B component. + * @param y Output parameter for the Y parameter. + * @param pb Output parameter for the Pb parameter. + * @param pr Output parameter for the Pr parameter. + */ +LIBCLUT_GCC_ONLY__(__attribute__((__leaf__))) +void (libclut_model_srgb_to_ypbpr)(double, double, double, double*, double*, double*); +#define libclut_model_srgb_to_ypbpr(r, g, b, y, pb, pr) \ + do \ + { \ + double r__ = libclut_model_standard_to_linear1(r); \ + double g__ = libclut_model_standard_to_linear1(g); \ + double b__ = libclut_model_standard_to_linear1(b); \ + double y__; \ + y__ = r__ * 2126 / 10000; \ + y__ += g__ * 7152 / 10000; \ + y__ += b__ * 722 / 10000; \ + *(y) = y__; \ + *(pb) = b__ - y__; \ + *(pr) = r__ - y__; \ + ; \ + } \ + while (0) + + +/** + * Convert from YPbPr to sRGB. + * + * Requires linking with '-lclut', or '-lm' if + * `libclut_model_linear_to_standard1` is not undefined. + * + * @param y The Y component. + * @param pb The Pb component. + * @param pr The Pr component. + * @param r Output parameter for the R parameter. + * @param g Output parameter for the G parameter. + * @param b Output parameter for the B parameter. + */ +LIBCLUT_GCC_ONLY__(__attribute__((__leaf__))) +void (libclut_model_ypbpr_to_srgb)(double, double, double, double*, double*, double*); +#define libclut_model_ypbpr_to_srgb(y, pb, pr, r, g, b) \ + do \ + { \ + double y__ = (y), r__ = (pr) + y__, g__, b__ = (pb) + y__; \ + y__ -= r__ * 2126 / 10000; \ + y__ -= b__ * 722 / 10000; \ + g__ = y__ * 10000 / 7152; \ + *(r) = libclut_model_linear_to_standard1(r__); \ + *(g) = libclut_model_linear_to_standard1(g__); \ + *(b) = libclut_model_linear_to_standard1(b__); \ + } \ + while (0) + + +/** + * Convert from sRGB to YCgCo. + * + * Requires linking with '-lclut', or '-lm' if + * `libclut_model_standard_to_linear1` is not undefined. + * + * @param r The R component. + * @param g The G component. + * @param b The B component. + * @param y Output parameter for the Y parameter. + * @param cg Output parameter for the Cg parameter. + * @param co Output parameter for the Co parameter. + */ +LIBCLUT_GCC_ONLY__(__attribute__((__leaf__))) +void (libclut_model_srgb_to_ycgco)(double, double, double, double*, double*, double*); +#define libclut_model_srgb_to_ycgco(r, g, b, y, cg, co) \ + do \ + { \ + double r__ = libclut_model_standard_to_linear1(r); \ + double g__ = libclut_model_standard_to_linear1(g); \ + double b__ = libclut_model_standard_to_linear1(b); \ + *(y) = r__ / 4 + g__ / 2 + b__ / 4; \ + *(cg) = r__ / -4 + g__ / 2 - b__ / 4; \ + *(co) = r__ / 2 - b__ / 2; \ + } \ + while (0) + + +/** + * Convert from YCgCo to sRGB. + * + * Requires linking with '-lclut', or '-lm' if + * `libclut_model_linear_to_standard1` is not undefined. + * + * @param y The Y component. + * @param cg The Cg component. + * @param co The Co component. + * @param r Output parameter for the R parameter. + * @param g Output parameter for the G parameter. + * @param b Output parameter for the B parameter. + */ +LIBCLUT_GCC_ONLY__(__attribute__((__leaf__))) +void (libclut_model_ycgco_to_srgb)(double, double, double, double*, double*, double*); +#define libclut_model_ycgco_to_srgb(y, cg, co, r, g, b) \ + do \ + { \ + double y__ = (y), cg__ = (cg), co__ = (co); \ + double r__ = y__ - cg__ + co__; \ + double g__ = y__ + cg__; \ + double b__ = y__ - cg__ - co__; \ + *(r) = libclut_model_linear_to_standard1(r__); \ + *(g) = libclut_model_linear_to_standard1(g__); \ + *(b) = libclut_model_linear_to_standard1(b__); \ + } \ + while (0) + + +/** + * Convert from CIE 1960 UCS to CIE XYZ. + * + * @param u The u component. + * @param v The v component. + * @param Y The Y component. + * @param x Output parameter for the X parameter. + * @param y Output parameter for the Y parameter. + * @param z Output parameter for the Z parameter. + */ +LIBCLUT_GCC_ONLY__(__attribute__((__leaf__))) +void (libclut_model_cie_1960_ucs_to_ciexyz)(double, double, double, double*, double*, double*); +#define libclut_model_cie_1960_ucs_to_ciexyz(u, v, Y, x, y, z) \ + do \ + { \ + double u__ = (u), v__ = (v), y__ = (Y); \ + *(y) = y__; \ + *(x) = 3 * y__ * u__ / (2 * v__); \ + *(z) = y__ * ((4 - u__) / (2 * v__) - 1) / 5; \ + } \ + while (0) + + +/** + * Convert from CIE XYZ to CIE 1960 UCS. + * + * @param x The X component. + * @param y The Y component. + * @param z The Z component. + * @param u Output parameter for the u parameter. + * @param v Output parameter for the v parameter. + * @param Y Output parameter for the Y parameter. + */ +LIBCLUT_GCC_ONLY__(__attribute__((__leaf__))) +void (libclut_model_ciexyz_to_cie_1960_ucs)(double, double, double, double*, double*, double*); +#define libclut_model_ciexyz_to_cie_1960_ucs(x, y, z, u, v, Y) \ + do \ + { \ + double x__ = (x), y__ = (y); \ + double d__ = x__ + 15 * y__ + 3 * (z); \ + *(u) = 4 * x__ / d__; \ + *(v) = 6 * y__ / d__; \ + *(Y) = y__; \ + } \ + while (0) + + +/** + * Convert from CIEUVW to CIE 1960 UCS. + * + * @param U:double The U* component. + * @param V:double The V* component. + * @param W:double The W* component. + * @param u0:double The u parameter for the white point. + * @param v0:double The v parameter for the white point. + * @param u:double* Output parameter for the u parameter. + * @param v:double* Output parameter for the v parameter. + * @param Y:double* Output parameter for the Y parameter. + */ +LIBCLUT_GCC_ONLY__(__attribute__((__leaf__))) +void (libclut_model_cieuvw_to_cie_1960_ucs)(double, double, double, double, double, + double*, double*, double*); +#define libclut_model_cieuvw_to_cie_1960_ucs(U, V, W, u0, v0, u, v, Y) \ + do \ + { \ + double w__ = (W), y__ = (w__ + 17) / 25; \ + *(Y) = y__ *= y__ * y__; \ + w__ *= 13; \ + *(u) = (U) / w__ + (u0); \ + *(v) = (V) / w__ + (v0); \ + } \ + while (0) + + +/** + * Convert from CIE 1960 UCS to CIEUVW. + * + * Requires linking with `-lm`. + * + * @param u:double The u component. + * @param v:double The v component. + * @param Y:double The Y component. + * @param u0:double The u parameter for the white point. + * @param v0:double The v parameter for the white point. + * @param U:double* Output parameter for the U* parameter. + * @param V:double* Output parameter for the V* parameter. + * @param W:double* Output parameter for the W* parameter. + */ +LIBCLUT_GCC_ONLY__(__attribute__((__leaf__))) +void (libclut_model_cie_1960_ucs_to_cieuvw)(double, double, double, double, double, + double*, double*, double*); +#define libclut_model_cie_1960_ucs_to_cieuvw(u, v, Y, u0, v0, U, V, W) \ + do \ + { \ + double w__ = 25 * cbrt(Y) - 17; \ + *(W) = w__; \ + w__ *= 13; \ + *(U) = w__ * ((u) - (u0)); \ + *(V) = w__ * ((v) - (v0)); \ + } \ + while (0) + + +/** * Create a matrix for converting values between * two RGB colour spaces. * @@ -1988,7 +2534,7 @@ int libclut_model_get_rgb_conversion_matrix(const libclut_rgb_colour_space_t*, */ LIBCLUT_GCC_ONLY__(__attribute__((__leaf__))) void (libclut_model_convert_rgb)(double, double, double, libclut_colour_space_conversion_matrix_t, - double *, double *, double *); + double*, double*, double*); #define libclut_model_convert_rgb(r, g, b, M, out_r, out_g, out_b) \ do \ { \ |