render/color: introduce wlr_color_transform_matrix

This is useful to perform color space conversions.
This commit is contained in:
Simon Ser 2025-10-28 18:37:37 +01:00
parent 17f3f28865
commit 2995f31102
3 changed files with 31 additions and 1 deletions

View file

@ -9,6 +9,7 @@ enum wlr_color_transform_type {
COLOR_TRANSFORM_INVERSE_EOTF, COLOR_TRANSFORM_INVERSE_EOTF,
COLOR_TRANSFORM_LCMS2, COLOR_TRANSFORM_LCMS2,
COLOR_TRANSFORM_LUT_3X1D, COLOR_TRANSFORM_LUT_3X1D,
COLOR_TRANSFORM_MATRIX,
COLOR_TRANSFORM_PIPELINE, COLOR_TRANSFORM_PIPELINE,
}; };
@ -40,6 +41,12 @@ struct wlr_color_transform_lut_3x1d {
size_t dim; size_t dim;
}; };
struct wlr_color_transform_matrix {
struct wlr_color_transform base;
float matrix[9];
};
struct wlr_color_transform_pipeline { struct wlr_color_transform_pipeline {
struct wlr_color_transform base; struct wlr_color_transform base;

View file

@ -141,6 +141,12 @@ struct wlr_color_transform *wlr_color_transform_init_linear_to_inverse_eotf(
struct wlr_color_transform *wlr_color_transform_init_lut_3x1d(size_t dim, struct wlr_color_transform *wlr_color_transform_init_lut_3x1d(size_t dim,
const uint16_t *r, const uint16_t *g, const uint16_t *b); const uint16_t *r, const uint16_t *g, const uint16_t *b);
/**
* Initialize a color transformation to apply a 3×3 matrix. Returns NULL on
* failure.
*/
struct wlr_color_transform *wlr_color_transform_init_matrix(const float matrix[static 9]);
/** /**
* Initialize a color transformation to apply a sequence of color transforms * Initialize a color transformation to apply a sequence of color transforms
* one after another. * one after another.

View file

@ -62,6 +62,16 @@ struct wlr_color_transform *wlr_color_transform_init_lut_3x1d(size_t dim,
return &tx->base; return &tx->base;
} }
struct wlr_color_transform *wlr_color_transform_init_matrix(const float matrix[static 9]) {
struct wlr_color_transform_matrix *tx = calloc(1, sizeof(*tx));
if (!tx) {
return NULL;
}
wlr_color_transform_init(&tx->base, COLOR_TRANSFORM_MATRIX);
memcpy(tx->matrix, matrix, sizeof(tx->matrix));
return &tx->base;
}
struct wlr_color_transform *wlr_color_transform_init_pipeline( struct wlr_color_transform *wlr_color_transform_init_pipeline(
struct wlr_color_transform **transforms, size_t len) { struct wlr_color_transform **transforms, size_t len) {
assert(len > 0); assert(len > 0);
@ -92,6 +102,7 @@ struct wlr_color_transform *wlr_color_transform_init_pipeline(
static void color_transform_destroy(struct wlr_color_transform *tr) { static void color_transform_destroy(struct wlr_color_transform *tr) {
switch (tr->type) { switch (tr->type) {
case COLOR_TRANSFORM_INVERSE_EOTF: case COLOR_TRANSFORM_INVERSE_EOTF:
case COLOR_TRANSFORM_MATRIX:
break; break;
case COLOR_TRANSFORM_LCMS2: case COLOR_TRANSFORM_LCMS2:
color_transform_lcms2_finish(color_transform_lcms2_from_base(tr)); color_transform_lcms2_finish(color_transform_lcms2_from_base(tr));
@ -226,6 +237,8 @@ static void color_transform_lut_3x1d_eval(struct wlr_color_transform_lut_3x1d *t
} }
} }
static void multiply_matrix_vector(float out[static 3], float m[static 9], const float v[static 3]);
void wlr_color_transform_eval(struct wlr_color_transform *tr, void wlr_color_transform_eval(struct wlr_color_transform *tr,
float out[static 3], const float in[static 3]) { float out[static 3], const float in[static 3]) {
switch (tr->type) { switch (tr->type) {
@ -238,6 +251,10 @@ void wlr_color_transform_eval(struct wlr_color_transform *tr,
case COLOR_TRANSFORM_LUT_3X1D: case COLOR_TRANSFORM_LUT_3X1D:
color_transform_lut_3x1d_eval(color_transform_lut_3x1d_from_base(tr), out, in); color_transform_lut_3x1d_eval(color_transform_lut_3x1d_from_base(tr), out, in);
break; break;
case COLOR_TRANSFORM_MATRIX:;
struct wlr_color_transform_matrix *matrix = wl_container_of(tr, matrix, base);
multiply_matrix_vector(out, matrix->matrix, in);
break;
case COLOR_TRANSFORM_PIPELINE:; case COLOR_TRANSFORM_PIPELINE:;
struct wlr_color_transform_pipeline *pipeline = struct wlr_color_transform_pipeline *pipeline =
wl_container_of(tr, pipeline, base); wl_container_of(tr, pipeline, base);
@ -264,7 +281,7 @@ void wlr_color_primaries_from_named(struct wlr_color_primaries *out,
abort(); abort();
} }
static void multiply_matrix_vector(float out[static 3], float m[static 9], float v[static 3]) { static void multiply_matrix_vector(float out[static 3], float m[static 9], const float v[static 3]) {
float result[3] = { float result[3] = {
m[0] * v[0] + m[1] * v[1] + m[2] * v[2], 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[3] * v[0] + m[4] * v[1] + m[5] * v[2],