mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-03-30 11:11:21 -04:00
render/color: add wlr_color_primaries_to_xyz()
This commit is contained in:
parent
d8ad4809fc
commit
156201fe71
3 changed files with 68 additions and 0 deletions
|
|
@ -45,4 +45,9 @@ struct wlr_color_transform_lut3d {
|
||||||
struct wlr_color_transform_lut3d *wlr_color_transform_lut3d_from_base(
|
struct wlr_color_transform_lut3d *wlr_color_transform_lut3d_from_base(
|
||||||
struct wlr_color_transform *tr);
|
struct wlr_color_transform *tr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the matrix to convert RGB color values to CIE 1931 XYZ.
|
||||||
|
*/
|
||||||
|
void wlr_color_primaries_to_xyz(const struct wlr_color_primaries *primaries, float matrix[static 9]);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,20 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CIE 1931 xy chromaticity coordinates.
|
||||||
|
*/
|
||||||
|
struct wlr_color_cie1931_xy {
|
||||||
|
float x, y;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Color primaries and white point describing a color volume.
|
||||||
|
*/
|
||||||
|
struct wlr_color_primaries {
|
||||||
|
struct wlr_color_cie1931_xy red, green, blue, white;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A color transformation formula, which maps a linear color space with
|
* A color transformation formula, which maps a linear color space with
|
||||||
* sRGB primaries to an output color space.
|
* sRGB primaries to an output color space.
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <wlr/render/color.h>
|
#include <wlr/render/color.h>
|
||||||
#include "render/color.h"
|
#include "render/color.h"
|
||||||
|
#include "util/matrix.h"
|
||||||
|
|
||||||
struct wlr_color_transform *wlr_color_transform_init_srgb(void) {
|
struct wlr_color_transform *wlr_color_transform_init_srgb(void) {
|
||||||
struct wlr_color_transform *tx = calloc(1, sizeof(struct wlr_color_transform));
|
struct wlr_color_transform *tx = calloc(1, sizeof(struct wlr_color_transform));
|
||||||
|
|
@ -50,3 +52,50 @@ struct wlr_color_transform_lut3d *wlr_color_transform_lut3d_from_base(
|
||||||
struct wlr_color_transform_lut3d *lut3d = wl_container_of(tr, lut3d, base);
|
struct wlr_color_transform_lut3d *lut3d = wl_container_of(tr, lut3d, base);
|
||||||
return lut3d;
|
return lut3d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void multiply_matrix_vector(float out[static 3], float m[static 9], float v[static 3]) {
|
||||||
|
float result[3] = {
|
||||||
|
m[0] * v[0] + m[1] * v[1] + m[2] * v[2],
|
||||||
|
m[3] * v[0] + m[4] * v[1] + m[5] * v[2],
|
||||||
|
m[6] * v[0] + m[7] * v[1] + m[8] * v[2],
|
||||||
|
};
|
||||||
|
memcpy(out, result, sizeof(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void xy_to_xyz(float out[static 3], struct wlr_color_cie1931_xy src) {
|
||||||
|
if (src.y == 0) {
|
||||||
|
out[0] = out[1] = out[2] = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
out[0] = src.x / src.y;
|
||||||
|
out[1] = 1;
|
||||||
|
out[2] = (1 - src.x - src.y) / src.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_color_primaries_to_xyz(const struct wlr_color_primaries *primaries, float matrix[static 9]) {
|
||||||
|
// See: http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
|
||||||
|
|
||||||
|
float r[3], g[3], b[3], w[3];
|
||||||
|
xy_to_xyz(r, primaries->red);
|
||||||
|
xy_to_xyz(g, primaries->green);
|
||||||
|
xy_to_xyz(b, primaries->blue);
|
||||||
|
xy_to_xyz(w, primaries->white);
|
||||||
|
|
||||||
|
float xyz_matrix[9] = {
|
||||||
|
r[0], g[0], b[0],
|
||||||
|
r[1], g[1], b[1],
|
||||||
|
r[2], g[2], b[2],
|
||||||
|
};
|
||||||
|
matrix_invert(xyz_matrix, xyz_matrix);
|
||||||
|
|
||||||
|
float S[3];
|
||||||
|
multiply_matrix_vector(S, xyz_matrix, w);
|
||||||
|
|
||||||
|
float result[] = {
|
||||||
|
S[0] * r[0], S[1] * g[0], S[2] * b[0],
|
||||||
|
S[0] * r[1], S[1] * g[1], S[2] * b[1],
|
||||||
|
S[0] * r[2], S[1] * g[2], S[2] * b[2],
|
||||||
|
};
|
||||||
|
memcpy(matrix, result, sizeof(result));
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue