diff options
| author | Mattias Andrée <maandree@kth.se> | 2023-01-22 01:06:50 +0100 | 
|---|---|---|
| committer | Mattias Andrée <maandree@kth.se> | 2023-01-22 01:08:26 +0100 | 
| commit | b8ece8550e52b26924e5096d03706dc379ec46d4 (patch) | |
| tree | 30f73817e7e5c69d066bedea2dddf5d27637eae8 | |
| parent | Fetching output colour space belongs in libfonts, not libglitter (diff) | |
| download | libglitter-b8ece8550e52b26924e5096d03706dc379ec46d4.tar.gz libglitter-b8ece8550e52b26924e5096d03706dc379ec46d4.tar.bz2 libglitter-b8ece8550e52b26924e5096d03706dc379ec46d4.tar.xz | |
Add libglitter_get_colour_space_conversion_matrix_{double,float}
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | libglitter.h | 42 | ||||
| -rw-r--r-- | libglitter_get_colour_space_conversion_matrix_double.c | 90 | ||||
| -rw-r--r-- | libglitter_get_colour_space_conversion_matrix_float.c | 25 | 
4 files changed, 159 insertions, 0 deletions
| @@ -27,6 +27,8 @@ OBJ =\  	libglitter_desaturate_float.o\  	libglitter_create_render_context.o\  	libglitter_free_render_context.o\ +	libglitter_get_colour_space_conversion_matrix_double.o\ +	libglitter_get_colour_space_conversion_matrix_float.o\  	libglitter_update_render_context.o  HDR =\ diff --git a/libglitter.h b/libglitter.h index 0fc5888..4cd64bf 100644 --- a/libglitter.h +++ b/libglitter.h @@ -7,6 +7,14 @@  /** + * The CIE xyY values of the D65 illuminant + */ +#define LIBGLITTER_ILLUMINANT_D65\ +	0.312726871026564878786047074755,\ +	0.329023206641284038376227272238, 1.0\ + + +/**   * Rendering context for an input raster's specifications   *    * Render context's are thread-safe, however updating them are not @@ -183,4 +191,38 @@ void libglitter_desaturate_double(double **, size_t, size_t, size_t, size_t, siz  void libglitter_desaturate_float(float **, size_t, size_t, size_t, size_t, size_t, float, const float *); +/** + * Get the matrix each pixel shall be multiplied with + * to convert it from the output's colour space to sRGB + *  + * This is useful when the output does not use sRGB, + * but the application does + *  + * @param  matrix   Output buffer for the conversion matrix + * @param  c1x      The CIE x value (as in CIE xyY) of the output's first primary colour + * @param  c1y      The CIE y value (as in CIE xyY) of the output's first primary colour + * @param  c2x      The CIE x value (as in CIE xyY) of the output's second primary colour + * @param  c2y      The CIE y value (as in CIE xyY) of the output's second primary colour + * @param  c3x      The CIE x value (as in CIE xyY) of the output's third primary colour + * @param  c3y      The CIE y value (as in CIE xyY) of the output's third primary colour + * @param  white_x  The CIE x value (as in CIE xyY) of the output's white point + * @param  white_y  The CIE y value (as in CIE xyY) of the output's white point + * @param  white_Y  The CIE Y value (as in CIE xyY) of the output's white point + *  + * `LIBGLITTER_ILLUMINANT_D65` can be input in place of + * `white_x, white_y, white_Y` (it expands to three arguments) + * if the output's whitepoint is the D65 illuminant + */ +void libglitter_get_colour_space_conversion_matrix_double(double[3][3], double, double, double, double, +                                                          double, double, double, double, double); + +/** + * This value is identical to `libglitter_get_colour_space_conversion_matrix_double`, + * apart from it parameter types, see `libglitter_get_colour_space_conversion_matrix_double` + * for details about this function + */ +void libglitter_get_colour_space_conversion_matrix_float(float[3][3], float, float, float, float, +                                                         float, float, float, float, float); + +  #endif diff --git a/libglitter_get_colour_space_conversion_matrix_double.c b/libglitter_get_colour_space_conversion_matrix_double.c new file mode 100644 index 0000000..fd3ecbc --- /dev/null +++ b/libglitter_get_colour_space_conversion_matrix_double.c @@ -0,0 +1,90 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +#define X(x, y) ((x) / (y)) +#define Z(x, y) ((1 - (x)) / (y) - 1) + + +#if defined(__GNUC__) && !defined(__clang__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunsuffixed-float-constants" +#endif + + +/** + * CIE XYZ-to-sRGB conversion matrix + */ +static const double srgb[3][3] = { +	{ 3.240446254647737056586720427731, -1.537134761820080353089679192635, -0.498530193022728773666329971093}, +	{-0.969266606244679751469561779231,  1.876011959788370209167851498933,  0.041556042214430065351304932619}, +	{ 0.055643503564352832235773149705, -0.204026179735960239147729566866,  1.057226567722703292062647051353}}; + + +#if defined(__GNUC__) && !defined(__clang__) +# pragma GCC diagnostic pop +#endif + + +static void +invert(double m[3][4]) +{ +	double t; +	size_t i; + +	/* Set m[0][0] = 1 */ for (t = m[0][0], i = 0; i < 4; i++)  m[0][i] /= t; +	/* Set m[1][0] = 0 */ for (t = m[1][0], i = 0; i < 4; i++)  m[1][i] -= t * m[0][i]; +	/* Set m[2][0] = 0 */ for (t = m[2][0], i = 0; i < 4; i++)  m[2][i] -= t * m[0][i]; + +	/* Set m[1][1] = 1 */ for (t = m[1][1], i = 1; i < 4; i++)  m[1][i] /= t; +	/* Set m[2][1] = 0 */ for (t = m[2][1], i = 1; i < 4; i++)  m[2][i] -= t * m[1][i]; +	/* Set m[0][1] = 0 */ for (t = m[0][1], i = 1; i < 4; i++)  m[0][i] -= t * m[1][i]; + +	/* Set m[2][2] = 1 */ for (t = m[2][2], i = 2; i < 4; i++)  m[2][i] /= t; +	/* Set m[1][2] = 0 */ for (t = m[1][2], i = 2; i < 4; i++)  m[1][i] -= t * m[2][i]; +	/* Set m[0][2] = 0 */ for (t = m[0][2], i = 2; i < 4; i++)  m[0][i] -= t * m[2][i]; +} + + +void +libglitter_get_colour_space_conversion_matrix_double(double matrix[3][3], double c1x, double c1y, +                                                     double c2x, double c2y, double c3x, double c3y, +                                                     double white_x, double white_y, double white_Y) +{ +	double mat[3][4]; +	double x1, x2, x3; +	double y1, y2, y3; +	double z1, z2, z3; + +	/* Get colour space in CIE XYZ */ +	mat[0][0] = x1 = X(c1x, c1y); +	mat[0][1] = x2 = X(c2x, c2y); +	mat[0][2] = x3 = X(c3x, c3y); +	mat[1][3] = X(white_x, white_y) * white_Y; +	mat[1][0] = 1; +	mat[1][1] = 1; +	mat[1][2] = 1; +	mat[1][3] = white_Y; +	mat[2][0] = z1 = Z(c1x, c1y); +	mat[2][1] = z2 = Z(c2x, c2y); +	mat[2][2] = z3 = Z(c3x, c3y); +	mat[2][3] = Z(white_x, white_y) * white_Y; +	invert(mat); +	y1 = mat[0][3]; +	y2 = mat[1][3]; +	y3 = mat[2][3]; + +	/* [[x1, x2, x3], [y1, y2, y3], [z1, z2, z3]] is +	 * the output RGB-to-CIE XYZ conversion matrix. It +	 * is multiplied by the CIE XYZ-to-sRGB conversion +	 * matrix to get the output RGB-to-sRGB conversion +	 * matrix. */ +	matrix[0][0] = x1 * srgb[0][0] + x2 * srgb[1][0] + x3 * srgb[2][0]; +	matrix[0][1] = x1 * srgb[0][1] + x2 * srgb[1][1] + x3 * srgb[2][1]; +	matrix[0][2] = x1 * srgb[0][2] + x2 * srgb[1][2] + x3 * srgb[2][2]; +	matrix[1][0] = y1 * srgb[0][0] + y2 * srgb[1][0] + y3 * srgb[2][0]; +	matrix[1][1] = y1 * srgb[0][1] + y2 * srgb[1][1] + y3 * srgb[2][1]; +	matrix[1][2] = y1 * srgb[0][2] + y2 * srgb[1][2] + y3 * srgb[2][2]; +	matrix[2][0] = z1 * srgb[0][0] + z2 * srgb[1][0] + z3 * srgb[2][0]; +	matrix[2][1] = z1 * srgb[0][1] + z2 * srgb[1][1] + z3 * srgb[2][1]; +	matrix[2][2] = z1 * srgb[0][2] + z2 * srgb[1][2] + z3 * srgb[2][2]; +} diff --git a/libglitter_get_colour_space_conversion_matrix_float.c b/libglitter_get_colour_space_conversion_matrix_float.c new file mode 100644 index 0000000..022c2a4 --- /dev/null +++ b/libglitter_get_colour_space_conversion_matrix_float.c @@ -0,0 +1,25 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +void +libglitter_get_colour_space_conversion_matrix_float(float matrix[3][3], float c1x, float c1y, +                                                    float c2x, float c2y, float c3x, float c3y, +                                                    float white_x, float white_y, float white_Y) +{ +	double double_matrix[3][3]; +	libglitter_get_colour_space_conversion_matrix_double(double_matrix, +	                                                     (double)c1x, (double)c1y, +	                                                     (double)c2x, (double)c2y, +	                                                     (double)c3x, (double)c3y, +	                                                     (double)white_x, (double)white_y, (double)white_Y); +	matrix[0][0] = (float)double_matrix[0][0]; +	matrix[0][1] = (float)double_matrix[0][1]; +	matrix[0][2] = (float)double_matrix[0][2]; +	matrix[1][0] = (float)double_matrix[1][0]; +	matrix[1][1] = (float)double_matrix[1][1]; +	matrix[1][2] = (float)double_matrix[1][2]; +	matrix[2][0] = (float)double_matrix[2][0]; +	matrix[2][1] = (float)double_matrix[2][1]; +	matrix[2][2] = (float)double_matrix[2][2]; +} | 
