color-lcms: extend color transformer

When parametric<->ICC color transformations are created in the future,
they need more than the icc_chain. Add the needed elements.

This path is used for the 3D LUT fallback when the steps in struct
weston_color_transform cannot be used.

Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This commit is contained in:
Pekka Paalanen 2025-06-05 13:21:38 +03:00
parent 92332f5640
commit 2b049cbad6
3 changed files with 57 additions and 2 deletions

View file

@ -201,9 +201,24 @@ struct color_transform_steps_mask {
uint8_t steps;
};
enum cmlcms_color_transformer_elem {
CMLCMS_TRANSFORMER_CURVE1 = 1 << 0,
CMLCMS_TRANSFORMER_LIN1 = 1 << 1,
CMLCMS_TRANSFORMER_ICC_CHAIN = 1 << 2,
CMLCMS_TRANSFORMER_LIN2 = 1 << 3,
CMLCMS_TRANSFORMER_CURVE2 = 1 << 4,
};
/** A complete color transformation to be computed on the CPU */
struct cmlcms_color_transformer {
/** Or'd together from enum cmlcms_color_transformer_elem */
uint8_t element_mask;
struct weston_color_curve curve1;
struct weston_color_mapping_matrix lin1;
cmsHTRANSFORM icc_chain;
struct weston_color_mapping_matrix lin2;
struct weston_color_curve curve2;
};
struct cmlcms_color_transform_recipe {

View file

@ -1378,8 +1378,11 @@ init_icc_to_icc_chain(struct cmlcms_color_transform *xform)
weston_assert_ptr_null(cm->base.compositor, xform->transformer.icc_chain);
xform->transformer.icc_chain = xform_realize_icc_chain(xform, chain, chain_len,
render_intent, allowed);
if (!xform->transformer.icc_chain)
return false;
return !!xform->transformer.icc_chain;
xform->transformer.element_mask |= CMLCMS_TRANSFORMER_ICC_CHAIN;
return true;
}
static void

View file

@ -30,6 +30,8 @@
#include <lcms2.h>
#include "color.h"
#include "color-operations.h"
#include "shared/weston-assert.h"
#include "color-lcms.h"
/** Release all transformer members. */
@ -57,5 +59,40 @@ cmlcms_color_transformer_eval(struct weston_compositor *compositor,
const struct weston_vec3f *src,
size_t len)
{
cmsDoTransform(t->icc_chain, src, dst, len);
const struct weston_vec3f *in = src;
struct weston_vec3f *end = dst + len;
struct weston_vec3f *out;
weston_assert_u8_ne(compositor, t->element_mask, 0);
if (t->element_mask & CMLCMS_TRANSFORMER_CURVE1) {
weston_color_curve_sample(compositor, &t->curve1, in, dst, len);
in = dst;
}
if (t->element_mask & CMLCMS_TRANSFORMER_LIN1) {
for (out = dst; out < end; out++, in++) {
*out = weston_v3f_add_v3f(weston_m3f_mul_v3f(t->lin1.matrix, *in),
t->lin1.offset);
}
in = dst;
}
if (t->element_mask & CMLCMS_TRANSFORMER_ICC_CHAIN) {
cmsDoTransform(t->icc_chain, in, dst, len);
in = dst;
}
if (t->element_mask & CMLCMS_TRANSFORMER_LIN2) {
for (out = dst; out < end; out++, in++) {
*out = weston_v3f_add_v3f(weston_m3f_mul_v3f(t->lin2.matrix, *in),
t->lin2.offset);
}
in = dst;
}
if (t->element_mask & CMLCMS_TRANSFORMER_CURVE2) {
weston_color_curve_sample(compositor, &t->curve2, in, dst, len);
in = dst;
}
}