mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2026-05-16 21:08:09 +02:00
color: add curve type enumerated
Not all color curves comes from parameters. For instance, with the CM&HDR protocol users can set color curves from tf_info. So let's add a new curve type to accommodate that. Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
This commit is contained in:
parent
0fe575b4a9
commit
209882c7d4
5 changed files with 178 additions and 0 deletions
|
|
@ -255,24 +255,62 @@ static const struct weston_color_primaries_info color_primaries_info_table[] = {
|
|||
},
|
||||
};
|
||||
|
||||
#define POWER_LAW_PARAMS(g) { g, 1.0, 0.0, 1.0, 0.0 }
|
||||
#define SRGB_PIECE_WISE_PARAMS { 2.4, 1.0f / 1.055f, 0.055f / 1.055f, 1.0f / 12.92f, 0.04045 }
|
||||
#define INVERSE_SRGB_PIECE_WISE_PARAMS { 1.0f / 2.4f, 1.055, -0.055, 12.92, 0.0031308 }
|
||||
|
||||
#define POWER_LAW(g, clamp) { \
|
||||
.type = WESTON_COLOR_CURVE_PARAMETRIC_TYPE_LINPOW, \
|
||||
.clamped_input = (clamp), \
|
||||
.params = { POWER_LAW_PARAMS(g), POWER_LAW_PARAMS(g), \
|
||||
POWER_LAW_PARAMS(g), } \
|
||||
}
|
||||
|
||||
#define SRGB_PIECE_WISE(clamp) { \
|
||||
.type = WESTON_COLOR_CURVE_PARAMETRIC_TYPE_LINPOW, \
|
||||
.clamped_input = (clamp), \
|
||||
.params = { SRGB_PIECE_WISE_PARAMS, SRGB_PIECE_WISE_PARAMS, \
|
||||
SRGB_PIECE_WISE_PARAMS, } \
|
||||
}
|
||||
|
||||
#define INVERSE_SRGB_PIECE_WISE(clamp) { \
|
||||
.type = WESTON_COLOR_CURVE_PARAMETRIC_TYPE_POWLIN, \
|
||||
.clamped_input = (clamp), \
|
||||
.params = { INVERSE_SRGB_PIECE_WISE_PARAMS, INVERSE_SRGB_PIECE_WISE_PARAMS, \
|
||||
INVERSE_SRGB_PIECE_WISE_PARAMS, } \
|
||||
}
|
||||
|
||||
static const struct weston_color_tf_info color_tf_info_table[] = {
|
||||
{
|
||||
.tf = WESTON_TF_BT1886,
|
||||
.desc = "BT.1886 transfer function",
|
||||
.protocol_tf = WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_BT1886,
|
||||
.count_parameters = 0,
|
||||
/**
|
||||
* NOTE: This is the BT.1886 special case of L_B = 0 and
|
||||
* L_W = 1.
|
||||
*/
|
||||
.curve_params_valid = true,
|
||||
.curve = POWER_LAW(2.4, true),
|
||||
.inverse_curve = POWER_LAW(1.0f / 2.4f, true),
|
||||
},
|
||||
{
|
||||
.tf = WESTON_TF_GAMMA22,
|
||||
.desc = "Assumed display gamma 2.2 transfer function",
|
||||
.protocol_tf = WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_GAMMA22,
|
||||
.count_parameters = 0,
|
||||
.curve_params_valid = true,
|
||||
.curve = POWER_LAW(2.2, true),
|
||||
.inverse_curve = POWER_LAW(1.0f / 2.2f, true),
|
||||
},
|
||||
{
|
||||
.tf = WESTON_TF_GAMMA28,
|
||||
.desc = "Assumed display gamma 2.8 transfer function",
|
||||
.protocol_tf = WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_GAMMA28,
|
||||
.count_parameters = 0,
|
||||
.curve_params_valid = true,
|
||||
.curve = POWER_LAW(2.8, true),
|
||||
.inverse_curve = POWER_LAW(1.0f / 2.8f, true),
|
||||
},
|
||||
{
|
||||
.tf = WESTON_TF_EXT_LINEAR,
|
||||
|
|
@ -285,12 +323,18 @@ static const struct weston_color_tf_info color_tf_info_table[] = {
|
|||
.desc = "sRGB piece-wise transfer function",
|
||||
.protocol_tf = WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_SRGB,
|
||||
.count_parameters = 0,
|
||||
.curve_params_valid = true,
|
||||
.curve = SRGB_PIECE_WISE(true),
|
||||
.inverse_curve = INVERSE_SRGB_PIECE_WISE(true),
|
||||
},
|
||||
{
|
||||
.tf = WESTON_TF_EXT_SRGB,
|
||||
.desc = "Extended sRGB piece-wise transfer function",
|
||||
.protocol_tf = WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_EXT_SRGB,
|
||||
.count_parameters = 0,
|
||||
.curve_params_valid = true,
|
||||
.curve = SRGB_PIECE_WISE(false),
|
||||
.inverse_curve = INVERSE_SRGB_PIECE_WISE(false),
|
||||
},
|
||||
{
|
||||
.tf = WESTON_TF_ST240,
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "color.h"
|
||||
#include <libweston/libweston.h>
|
||||
|
||||
struct weston_compositor;
|
||||
|
|
@ -113,6 +114,13 @@ struct weston_color_tf_info {
|
|||
* certain known functions that clients can define passing arbitrary
|
||||
* parameters. */
|
||||
bool count_parameters;
|
||||
|
||||
/** Are curve and inverse_curve valid? */
|
||||
bool curve_params_valid;
|
||||
|
||||
/** Parametric curves to which we can map the tf and its inverse. */
|
||||
struct weston_color_curve_parametric curve;
|
||||
struct weston_color_curve_parametric inverse_curve;
|
||||
};
|
||||
|
||||
const struct weston_color_feature_info *
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "shared/string-helpers.h"
|
||||
#include "shared/helpers.h"
|
||||
#include "shared/xalloc.h"
|
||||
#include "shared/weston-assert.h"
|
||||
|
||||
/**
|
||||
* Increase reference count of the color profile object
|
||||
|
|
@ -188,6 +189,54 @@ weston_color_profile_params_to_str(struct weston_color_profile_params *params,
|
|||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an enumerated color curve, returns an equivalent parametric curve.
|
||||
*
|
||||
* \param compositor The compositor instance.
|
||||
* \param curve The enumerated color curve.
|
||||
* \param out Where this stores the parametric curve.
|
||||
* \return True on success, false otherwise.
|
||||
*/
|
||||
WL_EXPORT bool
|
||||
weston_color_curve_enum_get_parametric(struct weston_compositor *compositor,
|
||||
const struct weston_color_curve_enum *curve,
|
||||
struct weston_color_curve_parametric *out)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
memset(out, 0, sizeof(*out));
|
||||
|
||||
/* This one is special, the only parametric TF we currently have. */
|
||||
if (curve->tf->tf == WESTON_TF_POWER) {
|
||||
out->type = WESTON_COLOR_CURVE_PARAMETRIC_TYPE_LINPOW;
|
||||
out->clamped_input = false;
|
||||
for (i = 0; i < 3; i++) {
|
||||
float exp = curve->params[i][0];
|
||||
/* LINPOW with such params matches pure power-law */
|
||||
out->params[i][0] = (curve->tf_direction == WESTON_FORWARD_TF) ?
|
||||
exp : 1.0f / exp; /* g */
|
||||
out->params[i][1] = 1.0; /* a */
|
||||
out->params[i][2] = 0.0; /* b */
|
||||
out->params[i][3] = 1.0; /* c */
|
||||
out->params[i][4] = 0.0; /* d */
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* No other TF's have params. */
|
||||
weston_assert_uint32_eq(compositor, curve->tf->count_parameters, 0);
|
||||
|
||||
if (!curve->tf->curve_params_valid)
|
||||
return false;
|
||||
|
||||
if (curve->tf_direction == WESTON_FORWARD_TF)
|
||||
*out = curve->tf->curve;
|
||||
else
|
||||
*out = curve->tf->inverse_curve;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase reference count of the color transform object
|
||||
*
|
||||
|
|
@ -266,6 +315,8 @@ curve_type_to_str(enum weston_color_curve_type curve_type)
|
|||
return "identity";
|
||||
case WESTON_COLOR_CURVE_TYPE_LUT_3x1D:
|
||||
return "3x1D LUT";
|
||||
case WESTON_COLOR_CURVE_TYPE_ENUM:
|
||||
return "enumerated";
|
||||
case WESTON_COLOR_CURVE_TYPE_PARAMETRIC:
|
||||
return "parametric";
|
||||
}
|
||||
|
|
@ -313,6 +364,10 @@ weston_color_transform_string(const struct weston_color_transform *xform)
|
|||
fprintf(fp, "%spre %s", sep, curve_type_to_str(pre_type));
|
||||
if (pre_type == WESTON_COLOR_CURVE_TYPE_LUT_3x1D)
|
||||
fprintf(fp, " [%u]", xform->pre_curve.u.lut_3x1d.optimal_len);
|
||||
else if (pre_type == WESTON_COLOR_CURVE_TYPE_ENUM)
|
||||
fprintf(fp, " [%s%s]",
|
||||
(xform->pre_curve.u.enumerated.tf_direction == WESTON_INVERSE_TF) ? "inverse " : "",
|
||||
xform->pre_curve.u.enumerated.tf->desc);
|
||||
else if (pre_type == WESTON_COLOR_CURVE_TYPE_PARAMETRIC)
|
||||
fprintf(fp, " [%s]",
|
||||
param_curve_type_to_str(xform->pre_curve.u.parametric.type));
|
||||
|
|
@ -330,6 +385,10 @@ weston_color_transform_string(const struct weston_color_transform *xform)
|
|||
fprintf(fp, "%spost %s", sep, curve_type_to_str(post_type));
|
||||
if (post_type == WESTON_COLOR_CURVE_TYPE_LUT_3x1D)
|
||||
fprintf(fp, " [%u]", xform->post_curve.u.lut_3x1d.optimal_len);
|
||||
else if (post_type == WESTON_COLOR_CURVE_TYPE_ENUM)
|
||||
fprintf(fp, " [%s%s]",
|
||||
(xform->post_curve.u.enumerated.tf_direction == WESTON_INVERSE_TF) ? "inverse " : "",
|
||||
xform->post_curve.u.enumerated.tf->desc);
|
||||
else if (post_type == WESTON_COLOR_CURVE_TYPE_PARAMETRIC)
|
||||
fprintf(fp, " [%s]",
|
||||
param_curve_type_to_str(xform->post_curve.u.parametric.type));
|
||||
|
|
|
|||
|
|
@ -225,6 +225,9 @@ enum weston_color_curve_type {
|
|||
/** Three-channel, one-dimensional look-up table */
|
||||
WESTON_COLOR_CURVE_TYPE_LUT_3x1D,
|
||||
|
||||
/** Enumerated color curve */
|
||||
WESTON_COLOR_CURVE_TYPE_ENUM,
|
||||
|
||||
/** Parametric color curve */
|
||||
WESTON_COLOR_CURVE_TYPE_PARAMETRIC,
|
||||
};
|
||||
|
|
@ -255,6 +258,24 @@ struct weston_color_curve_lut_3x1d {
|
|||
unsigned optimal_len;
|
||||
};
|
||||
|
||||
/** Direct or inverse of a tf. */
|
||||
enum weston_tf_direction {
|
||||
WESTON_FORWARD_TF,
|
||||
WESTON_INVERSE_TF,
|
||||
};
|
||||
|
||||
/** Enumerated color curve */
|
||||
struct weston_color_curve_enum {
|
||||
const struct weston_color_tf_info *tf;
|
||||
|
||||
/* Determines if the direct or inverse of the tf should be used. */
|
||||
enum weston_tf_direction tf_direction;
|
||||
|
||||
/* Some tf are parametric, and we keep the params here. They may be
|
||||
* different for each color channel, and channels are in RGB order. */
|
||||
float params[3][MAX_PARAMS_TF];
|
||||
};
|
||||
|
||||
/** Parametric color curve parameters */
|
||||
struct weston_color_curve_parametric {
|
||||
enum weston_color_curve_parametric_type type;
|
||||
|
|
@ -286,6 +307,7 @@ struct weston_color_curve {
|
|||
union {
|
||||
/* identity: no parameters */
|
||||
struct weston_color_curve_lut_3x1d lut_3x1d;
|
||||
struct weston_color_curve_enum enumerated;
|
||||
struct weston_color_curve_parametric parametric;
|
||||
} u;
|
||||
};
|
||||
|
|
@ -620,6 +642,11 @@ char *
|
|||
weston_color_profile_params_to_str(struct weston_color_profile_params *params,
|
||||
const char *ident);
|
||||
|
||||
bool
|
||||
weston_color_curve_enum_get_parametric(struct weston_compositor *compositor,
|
||||
const struct weston_color_curve_enum *curve,
|
||||
struct weston_color_curve_parametric *out);
|
||||
|
||||
struct weston_color_transform *
|
||||
weston_color_transform_ref(struct weston_color_transform *xform);
|
||||
|
||||
|
|
|
|||
|
|
@ -167,6 +167,38 @@ gl_color_curve_parametric(struct gl_renderer *gr,
|
|||
weston_assert_not_reached(gr->compositor, "unknown parametric color curve");
|
||||
}
|
||||
|
||||
static bool
|
||||
gl_color_curve_enum(struct gl_renderer *gr,
|
||||
struct gl_renderer_color_curve *gl_curve,
|
||||
const struct weston_color_curve *curve)
|
||||
{
|
||||
struct weston_color_curve_parametric parametric;
|
||||
bool ret;
|
||||
|
||||
/* Lower TF to a parametric curve. */
|
||||
ret = weston_color_curve_enum_get_parametric(gr->compositor,
|
||||
&curve->u.enumerated,
|
||||
¶metric);
|
||||
if (!ret)
|
||||
return false;
|
||||
|
||||
/* Handle parametric curve that we got from TF. */
|
||||
|
||||
ARRAY_COPY(gl_curve->u.parametric.params, parametric.params);
|
||||
gl_curve->u.parametric.clamped_input = parametric.clamped_input;
|
||||
|
||||
switch(parametric.type) {
|
||||
case WESTON_COLOR_CURVE_PARAMETRIC_TYPE_LINPOW:
|
||||
gl_curve->type = SHADER_COLOR_CURVE_LINPOW;
|
||||
return true;
|
||||
case WESTON_COLOR_CURVE_PARAMETRIC_TYPE_POWLIN:
|
||||
gl_curve->type = SHADER_COLOR_CURVE_POWLIN;
|
||||
return true;
|
||||
}
|
||||
|
||||
weston_assert_not_reached(gr->compositor, "unknown parametric color curve");
|
||||
}
|
||||
|
||||
static bool
|
||||
gl_color_curve_lut_3x1d(struct gl_renderer *gr,
|
||||
struct gl_renderer_color_curve *gl_curve,
|
||||
|
|
@ -285,6 +317,10 @@ gl_renderer_color_transform_from(struct gl_renderer *gr,
|
|||
ok = gl_color_curve_parametric(gr, &gl_xform->pre_curve,
|
||||
&xform->pre_curve);
|
||||
break;
|
||||
case WESTON_COLOR_CURVE_TYPE_ENUM:
|
||||
ok = gl_color_curve_enum(gr, &gl_xform->pre_curve,
|
||||
&xform->pre_curve);
|
||||
break;
|
||||
}
|
||||
if (!ok) {
|
||||
gl_renderer_color_transform_destroy(gl_xform);
|
||||
|
|
@ -323,6 +359,10 @@ gl_renderer_color_transform_from(struct gl_renderer *gr,
|
|||
ok = gl_color_curve_parametric(gr, &gl_xform->post_curve,
|
||||
&xform->post_curve);
|
||||
break;
|
||||
case WESTON_COLOR_CURVE_TYPE_ENUM:
|
||||
ok = gl_color_curve_enum(gr, &gl_xform->post_curve,
|
||||
&xform->post_curve);
|
||||
break;
|
||||
}
|
||||
if (!ok) {
|
||||
gl_renderer_color_transform_destroy(gl_xform);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue