mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2026-05-05 01:48:00 +02:00
color: rename to_shaper_plus_3dlut() to to_clut()
This name is quite long and awkward to use in certain functions. On ICC nomenclature, cLUT is a multidimensional LUT with a shaper (1D LUT) in front of it. So let's just call it to_clut() to simplify. Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
This commit is contained in:
parent
348141f899
commit
e093d21016
4 changed files with 52 additions and 54 deletions
|
|
@ -2195,8 +2195,8 @@ lut_3x1d_from_blend_to_output(struct weston_compositor *compositor,
|
|||
/**
|
||||
* We expect steps to be valid for blend-to-output, as LittleCMS is
|
||||
* always able to optimize such xform. If that's invalid, we'd need to
|
||||
* use to_shaper_plus_3dlut() to offload the xform, but the DRM API
|
||||
* currently only supports us programming a LUT after blending.
|
||||
* use to_clut() to offload the xform, but the DRM API currently only
|
||||
* supports us programming a LUT after blending.
|
||||
*/
|
||||
if (!xform->steps_valid) {
|
||||
str_printf(err_msg, "xform color steps are invalid");
|
||||
|
|
|
|||
|
|
@ -2032,10 +2032,10 @@ cmlcms_color_transform_recipe_string(const struct cmlcms_color_transform_recipe
|
|||
}
|
||||
|
||||
static bool
|
||||
build_3d_lut(struct weston_compositor *compositor,
|
||||
const struct cmlcms_color_transformer *transformer,
|
||||
unsigned int len_shaper, const float *shaper,
|
||||
unsigned int len_lut3d, float *lut3d)
|
||||
build_clut(struct weston_compositor *compositor,
|
||||
const struct cmlcms_color_transformer *transformer,
|
||||
unsigned int len_shaper, const float *shaper,
|
||||
unsigned int len_clut, float *clut)
|
||||
{
|
||||
const float *const red_curve = &shaper[0];
|
||||
const float *const green_curve = &shaper[len_shaper];
|
||||
|
|
@ -2051,27 +2051,26 @@ build_3d_lut(struct weston_compositor *compositor,
|
|||
* Ensure the indices and byte counts cannot overflow,
|
||||
* and memory usage does not get ridiculous. Arbitrary limit.
|
||||
*/
|
||||
weston_assert_u32_lt(compositor, len_lut3d, 100);
|
||||
weston_assert_u32_lt(compositor, len_clut, 100);
|
||||
|
||||
/*
|
||||
* A temporary allocation that holds two 1D LUTs of length len_lut3d
|
||||
* and one scratch array of vec3f of length len_lut3d.
|
||||
* A temporary allocation that holds two 1D LUTs of length len_clut
|
||||
* and one scratch array of vec3f of length len_clut.
|
||||
*/
|
||||
const uint32_t bytes_per_elem = 2 * sizeof (float) + sizeof *rgb_in;
|
||||
tmp = malloc(len_lut3d * bytes_per_elem);
|
||||
tmp = malloc(len_clut * bytes_per_elem);
|
||||
|
||||
inverse_r = &tmp[0];
|
||||
inverse_g = &tmp[len_lut3d];
|
||||
rgb_in = (struct weston_vec3f *)&tmp[2 * len_lut3d];
|
||||
|
||||
inverse_g = &tmp[len_clut];
|
||||
rgb_in = (struct weston_vec3f *)&tmp[2 * len_clut];
|
||||
/*
|
||||
* For each channel, use the shaper to compute the value x such that
|
||||
* y(x) = index / (len - 1). As the shaper is a LUT, we find the closest
|
||||
* neighbors of such point (x, y) and then use linear interpolation to
|
||||
* estimate x.
|
||||
*/
|
||||
for (i = 0; i < len_lut3d; i++) {
|
||||
float y = (float)i / (len_lut3d - 1);
|
||||
for (i = 0; i < len_clut; i++) {
|
||||
float y = (float)i / (len_clut - 1);
|
||||
inverse_r[i] = weston_inverse_evaluate_lut1d(compositor,
|
||||
len_shaper,
|
||||
red_curve,
|
||||
|
|
@ -2083,9 +2082,9 @@ build_3d_lut(struct weston_compositor *compositor,
|
|||
}
|
||||
|
||||
/*
|
||||
* Fill in the 3D LUT: LUT(Rin, Gin, Bin) = { Rout, Gout, Bout }
|
||||
* Fill in the 3D cLUT: LUT(Rin, Gin, Bin) = { Rout, Gout, Bout }
|
||||
* Each of Rin, Gin and Bin varies from 0.0 to 1.0. The range [0.0, 1.0]
|
||||
* is evenly divided into len_lut3d number of sampling points. The
|
||||
* is evenly divided into len_clut number of sampling points. The
|
||||
* indices of the sampling points are index_r, index_g, index_b.
|
||||
*
|
||||
* To compute { Rout, Gout, Bout }, first Rin, Gin, Bin must go through
|
||||
|
|
@ -2095,29 +2094,29 @@ build_3d_lut(struct weston_compositor *compositor,
|
|||
* separable.
|
||||
*
|
||||
* The next step is not separable, so we iterate through all points in
|
||||
* the 3D volume. The points are transformed len_lut3d points at a time
|
||||
* the 3D volume. The points are transformed len_clut points at a time
|
||||
* (rgb_in array) to strike a balance between the number of function
|
||||
* calls and the memory requirements.
|
||||
*/
|
||||
for (index_b = 0; index_b < len_lut3d; index_b++) {
|
||||
for (index_b = 0; index_b < len_clut; index_b++) {
|
||||
float inverse_b = weston_inverse_evaluate_lut1d(compositor,
|
||||
len_shaper,
|
||||
blue_curve,
|
||||
(float)index_b / (len_lut3d - 1));
|
||||
for (i = 0; i < len_lut3d; i++)
|
||||
(float)index_b / (len_clut - 1));
|
||||
for (i = 0; i < len_clut; i++)
|
||||
rgb_in[i].b = inverse_b;
|
||||
|
||||
for (index_g = 0; index_g < len_lut3d; index_g++) {
|
||||
for (index_r = 0; index_r < len_lut3d; index_r++) {
|
||||
for (index_g = 0; index_g < len_clut; index_g++) {
|
||||
for (index_r = 0; index_r < len_clut; index_r++) {
|
||||
rgb_in[index_r].g = inverse_g[index_g];
|
||||
rgb_in[index_r].r = inverse_r[index_r];
|
||||
}
|
||||
|
||||
index_r = 0;
|
||||
i = 3 * (index_r + len_lut3d * (index_g + len_lut3d * index_b));
|
||||
i = 3 * (index_r + len_clut * (index_g + len_clut * index_b));
|
||||
cmlcms_color_transformer_eval(compositor, transformer,
|
||||
(struct weston_vec3f *)&lut3d[i],
|
||||
rgb_in, len_lut3d);
|
||||
(struct weston_vec3f *)&clut[i],
|
||||
rgb_in, len_clut);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2230,16 +2229,16 @@ out:
|
|||
|
||||
/**
|
||||
* Based on [1]. We get the transformer and decompose into a shaper
|
||||
* (3x1D LUT) + 3D LUT. With that, we can reduce the 3D LUT dimension size
|
||||
* (3x1D LUT) + 3D cLUT. With that, we can reduce the 3D LUT dimension size
|
||||
* without losing precision. 3D LUT dimension size is problematic because it
|
||||
* demands n³ memory.
|
||||
*
|
||||
* [1] https://www.littlecms.com/ASICprelinerization_CGIV08.pdf
|
||||
*/
|
||||
static bool
|
||||
xform_to_shaper_plus_3dlut(struct weston_color_transform *xform_base,
|
||||
uint32_t len_shaper, float *shaper,
|
||||
uint32_t len_lut3d, float *lut3d)
|
||||
xform_to_clut(struct weston_color_transform *xform_base,
|
||||
uint32_t len_shaper, float *shaper,
|
||||
uint32_t len_clut, float *clut)
|
||||
{
|
||||
struct cmlcms_color_transform *xform = to_cmlcms_xform(xform_base);
|
||||
struct weston_compositor *compositor = xform_base->cm->compositor;
|
||||
|
|
@ -2250,8 +2249,8 @@ xform_to_shaper_plus_3dlut(struct weston_color_transform *xform_base,
|
|||
if (!ret)
|
||||
return false;
|
||||
|
||||
ret = build_3d_lut(compositor, &xform->transformer,
|
||||
len_shaper, shaper, len_lut3d, lut3d);
|
||||
ret = build_clut(compositor, &xform->transformer,
|
||||
len_shaper, shaper, len_clut, clut);
|
||||
if (!ret)
|
||||
return false;
|
||||
|
||||
|
|
@ -2280,7 +2279,7 @@ cmlcms_color_transform_create(struct weston_color_manager_lcms *cm,
|
|||
xform = xzalloc(sizeof *xform);
|
||||
weston_color_transform_init(&xform->base, &cm->base);
|
||||
wl_list_init(&xform->link);
|
||||
xform->base.to_shaper_plus_3dlut = xform_to_shaper_plus_3dlut;
|
||||
xform->base.to_clut = xform_to_clut;
|
||||
cmlcms_color_transform_recipe_copy(&xform->search_key, recipe);
|
||||
|
||||
weston_log_scope_printf(cm->transforms_scope,
|
||||
|
|
|
|||
|
|
@ -383,8 +383,8 @@ struct weston_color_transform {
|
|||
/**
|
||||
* When this is true, users are allowed to use the steps described below
|
||||
* (pre curve, color mapping and post curve) and implement the color
|
||||
* transformation themselves. Otherwise this is forbidden and
|
||||
* to_shaper_plus_3dlut() must be used.
|
||||
* transformation themselves. Otherwise this is forbidden and to_clut()
|
||||
* must be used.
|
||||
*/
|
||||
bool steps_valid;
|
||||
|
||||
|
|
@ -403,23 +403,23 @@ struct weston_color_transform {
|
|||
struct weston_color_curve post_curve;
|
||||
|
||||
/**
|
||||
* Decompose the color transformation into a shaper (3x1D LUT) and a 3D
|
||||
* LUT.
|
||||
* Decompose the color transformation into a shaper (3x1D LUT) followed
|
||||
* by a 3D cLUT.
|
||||
*
|
||||
* \param xform_base The color transformation to decompose.
|
||||
* \param len_shaper Number of taps in each of the 1D LUT.
|
||||
* \param shaper Where the shaper is saved, caller's responsibility to
|
||||
* allocate.
|
||||
* \param len_lut3d The 3D LUT's length for each dimension.
|
||||
* \param lut3d Where the 3D LUT is saved, caller's responsibility to
|
||||
* allocate. Its layout on memory is: lut3d[B][G][R], i.e. R is the
|
||||
* \param len_clut The 3D cLUT's length for each dimension.
|
||||
* \param clut Where the 3D cLUT is saved, caller's responsibility to
|
||||
* allocate. Its layout on memory is: clut[B][G][R], i.e. R is the
|
||||
* innermost and its index grow faster, followed by G and then B.
|
||||
* \return True on success, false otherwise.
|
||||
*/
|
||||
bool
|
||||
(*to_shaper_plus_3dlut)(struct weston_color_transform *xform_base,
|
||||
uint32_t len_shaper, float *shaper,
|
||||
uint32_t len_lut3d, float *lut3d);
|
||||
(*to_clut)(struct weston_color_transform *xform_base,
|
||||
uint32_t len_shaper, float *shaper,
|
||||
uint32_t len_clut, float *clut);
|
||||
};
|
||||
|
||||
struct weston_cvd_correction {
|
||||
|
|
|
|||
|
|
@ -378,9 +378,9 @@ gl_renderer_color_transform_create_3dlut(struct gl_renderer *gr,
|
|||
{
|
||||
struct gl_renderer_color_transform *gl_xform = NULL;
|
||||
float *shaper = NULL;
|
||||
float *lut3d = NULL;
|
||||
float *clut = NULL;
|
||||
uint32_t len_shaper;
|
||||
uint32_t len_lut3d;
|
||||
uint32_t len_clut;
|
||||
bool ok;
|
||||
|
||||
/**
|
||||
|
|
@ -388,22 +388,21 @@ gl_renderer_color_transform_create_3dlut(struct gl_renderer *gr,
|
|||
* excessive memory consumption.
|
||||
*/
|
||||
len_shaper = 1024;
|
||||
len_lut3d = 33;
|
||||
len_clut = 33;
|
||||
|
||||
shaper = zalloc(len_shaper * 3 * sizeof(*shaper));
|
||||
if (!shaper)
|
||||
goto err;
|
||||
|
||||
lut3d = zalloc(3 * len_lut3d * len_lut3d * len_lut3d * sizeof(*lut3d));
|
||||
if (!lut3d)
|
||||
clut = zalloc(3 * len_clut * len_clut * len_clut * sizeof(*clut));
|
||||
if (!clut)
|
||||
goto err;
|
||||
|
||||
gl_xform = gl_renderer_color_transform_create(xform);
|
||||
if (!gl_xform)
|
||||
goto err;
|
||||
|
||||
ok = xform->to_shaper_plus_3dlut(xform, len_shaper, shaper,
|
||||
len_lut3d, lut3d);
|
||||
ok = xform->to_clut(xform, len_shaper, shaper, len_clut, clut);
|
||||
if (!ok)
|
||||
goto err;
|
||||
|
||||
|
|
@ -413,18 +412,18 @@ gl_renderer_color_transform_create_3dlut(struct gl_renderer *gr,
|
|||
goto err;
|
||||
|
||||
gl_color_mapping_lut_3d_init(gr, &gl_xform->mapping,
|
||||
len_lut3d, lut3d);
|
||||
len_clut, clut);
|
||||
|
||||
free(shaper);
|
||||
free(lut3d);
|
||||
free(clut);
|
||||
|
||||
return gl_xform;
|
||||
|
||||
err:
|
||||
if (shaper)
|
||||
free(shaper);
|
||||
if (lut3d)
|
||||
free(lut3d);
|
||||
if (clut)
|
||||
free(clut);
|
||||
if (gl_xform)
|
||||
gl_renderer_color_transform_destroy(gl_xform);
|
||||
return NULL;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue