mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2025-12-25 00:10:10 +01:00
frontend: allow creating custom param color profiles from .ini
This allow users to specify a fully custom parametric color profile in weston.ini for a certain output. Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com> Co-authored-by: Pekka Paalanen <pekka.paalanen@collabora.com> Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This commit is contained in:
parent
360eef9663
commit
854457524c
2 changed files with 610 additions and 6 deletions
378
frontend/main.c
378
frontend/main.c
|
|
@ -55,6 +55,7 @@
|
||||||
#include "shared/process-util.h"
|
#include "shared/process-util.h"
|
||||||
#include "shared/string-helpers.h"
|
#include "shared/string-helpers.h"
|
||||||
#include "shared/xalloc.h"
|
#include "shared/xalloc.h"
|
||||||
|
#include "shared/weston-assert.h"
|
||||||
#include "git-version.h"
|
#include "git-version.h"
|
||||||
#include <libweston/version.h>
|
#include <libweston/version.h>
|
||||||
#include "weston.h"
|
#include "weston.h"
|
||||||
|
|
@ -1354,6 +1355,357 @@ weston_log_indent_multiline(int indent, const char *multiline)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
parse_float_array(float *values, size_t len_values, const char *str, char **errmsg)
|
||||||
|
{
|
||||||
|
struct weston_string_array elems;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
elems = weston_parse_space_separated_list(str);
|
||||||
|
if (elems.len != len_values) {
|
||||||
|
if (len_values == 1) {
|
||||||
|
str_printf(errmsg, "Needed only one number, got %zu numbers.",
|
||||||
|
elems.len);
|
||||||
|
} else {
|
||||||
|
str_printf(errmsg,
|
||||||
|
"Needed exactly %zu numbers separated by whitespace, got %zu.",
|
||||||
|
len_values, elems.len);
|
||||||
|
}
|
||||||
|
weston_string_array_fini(&elems);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < len_values; i++) {
|
||||||
|
if (!safe_strtofloat(elems.array[i], &values[i])) {
|
||||||
|
str_printf(errmsg, "'%s' is not a number.", elems.array[i]);
|
||||||
|
weston_string_array_fini(&elems);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
weston_string_array_fini(&elems);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
parse_CIExy(struct weston_CIExy *chrom, const char *str, char **errmsg)
|
||||||
|
{
|
||||||
|
float val[2];
|
||||||
|
|
||||||
|
if (!parse_float_array(val, ARRAY_LENGTH(val), str, errmsg))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
chrom->x = val[0];
|
||||||
|
chrom->y = val[1];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct weston_enum_map config_primaries_map[] = {
|
||||||
|
{ "srgb", WESTON_PRIMARIES_CICP_SRGB },
|
||||||
|
{ "pal_m", WESTON_PRIMARIES_CICP_PAL_M },
|
||||||
|
{ "pal", WESTON_PRIMARIES_CICP_PAL },
|
||||||
|
{ "ntsc", WESTON_PRIMARIES_CICP_NTSC },
|
||||||
|
{ "generic_film", WESTON_PRIMARIES_CICP_GENERIC_FILM },
|
||||||
|
{ "bt2020", WESTON_PRIMARIES_CICP_BT2020 },
|
||||||
|
{ "cie1931_xyz", WESTON_PRIMARIES_CICP_CIE1931_XYZ },
|
||||||
|
{ "dci_p3", WESTON_PRIMARIES_CICP_DCI_P3 },
|
||||||
|
{ "display_p3", WESTON_PRIMARIES_CICP_DISPLAY_P3 },
|
||||||
|
{ "adobe_rgb", WESTON_PRIMARIES_ADOBE_RGB },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct weston_enum_map config_tf_map[] = {
|
||||||
|
{ "bt1886", WESTON_TF_BT1886 },
|
||||||
|
{ "gamma22", WESTON_TF_GAMMA22 },
|
||||||
|
{ "gamma28", WESTON_TF_GAMMA28 },
|
||||||
|
{ "st240", WESTON_TF_ST240 },
|
||||||
|
{ "st428", WESTON_TF_ST428 },
|
||||||
|
{ "st2084", WESTON_TF_ST2084_PQ },
|
||||||
|
{ "linear", WESTON_TF_EXT_LINEAR },
|
||||||
|
{ "log100", WESTON_TF_LOG_100 },
|
||||||
|
{ "log316", WESTON_TF_LOG_316 },
|
||||||
|
{ "xvycc", WESTON_TF_XVYCC },
|
||||||
|
{ "hlg", WESTON_TF_HLG },
|
||||||
|
};
|
||||||
|
|
||||||
|
enum profile_parameter_group {
|
||||||
|
PARAMS_GROUP_PRIMARIES = 1 << 0,
|
||||||
|
PARAMS_GROUP_PRIMARIES_NAMED = 1 << 1,
|
||||||
|
PARAMS_GROUP_TF_NAMED = 1 << 2,
|
||||||
|
PARAMS_GROUP_TF_POWER = 1 << 3,
|
||||||
|
PARAMS_GROUP_LUMINANCE = 1 << 4,
|
||||||
|
PARAMS_GROUP_TARGET_PRIMARIES = 1 << 5,
|
||||||
|
PARAMS_GROUP_TARGET_PRIMARIES_NAMED = 1 << 6,
|
||||||
|
PARAMS_GROUP_TARGET_LUMINANCE = 1 << 7,
|
||||||
|
PARAMS_GROUP_MAX_FALL = 1 << 8,
|
||||||
|
PARAMS_GROUP_MAX_CLL = 1 << 9,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct weston_enum_map profile_parameter_group_names[] = {
|
||||||
|
{ "signaling primaries", PARAMS_GROUP_PRIMARIES },
|
||||||
|
{ "signaling luminances", PARAMS_GROUP_LUMINANCE },
|
||||||
|
{ "target primaries", PARAMS_GROUP_TARGET_PRIMARIES },
|
||||||
|
{ "target luminances", PARAMS_GROUP_TARGET_LUMINANCE },
|
||||||
|
};
|
||||||
|
|
||||||
|
struct config_color_params_type {
|
||||||
|
enum {
|
||||||
|
TYPE_FLOAT,
|
||||||
|
TYPE_CIEXY,
|
||||||
|
TYPE_ENUM,
|
||||||
|
} data_type;
|
||||||
|
const struct weston_enum_map *map;
|
||||||
|
size_t map_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A scalar floating-point value (float) */
|
||||||
|
static const struct config_color_params_type type_float = {
|
||||||
|
TYPE_FLOAT, NULL, 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A CIE 1931 xy floating-point value pair (struct weston_CIExy) */
|
||||||
|
static const struct config_color_params_type type_ciexy = {
|
||||||
|
TYPE_CIEXY, NULL, 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Enumerated primaries and white point (uint32_t) */
|
||||||
|
static const struct config_color_params_type type_prims = {
|
||||||
|
TYPE_ENUM, config_primaries_map, ARRAY_LENGTH(config_primaries_map),
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Enumerated transfer functions (uint32_t) */
|
||||||
|
static const struct config_color_params_type type_tfs = {
|
||||||
|
TYPE_ENUM, config_tf_map, ARRAY_LENGTH(config_tf_map),
|
||||||
|
};
|
||||||
|
|
||||||
|
struct config_color_params {
|
||||||
|
uint32_t group_mask;
|
||||||
|
|
||||||
|
struct weston_color_gamut prim;
|
||||||
|
uint32_t prim_named;
|
||||||
|
uint32_t tf_named;
|
||||||
|
float tf_power;
|
||||||
|
float prim_lum[2];
|
||||||
|
float ref_lum;
|
||||||
|
struct weston_color_gamut target_prim;
|
||||||
|
uint32_t target_named;
|
||||||
|
float target_lum[2];
|
||||||
|
float max_cll, max_fall;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool
|
||||||
|
config_color_params_parse(struct config_color_params *dst,
|
||||||
|
struct weston_config_section *section,
|
||||||
|
const char *section_name,
|
||||||
|
const char *msgpfx,
|
||||||
|
struct weston_compositor *compositor)
|
||||||
|
{
|
||||||
|
const struct {
|
||||||
|
const char *name;
|
||||||
|
const struct config_color_params_type *type;
|
||||||
|
void *data;
|
||||||
|
enum profile_parameter_group group;
|
||||||
|
} keys[] = {
|
||||||
|
{ "prim_red", &type_ciexy, &dst->prim.primary[0], PARAMS_GROUP_PRIMARIES },
|
||||||
|
{ "prim_green", &type_ciexy, &dst->prim.primary[1], PARAMS_GROUP_PRIMARIES },
|
||||||
|
{ "prim_blue", &type_ciexy, &dst->prim.primary[2], PARAMS_GROUP_PRIMARIES },
|
||||||
|
{ "prim_white", &type_ciexy, &dst->prim.white_point, PARAMS_GROUP_PRIMARIES },
|
||||||
|
{ "prim_named", &type_prims, &dst->prim_named, PARAMS_GROUP_PRIMARIES_NAMED },
|
||||||
|
{ "tf_named", &type_tfs, &dst->tf_named, PARAMS_GROUP_TF_NAMED },
|
||||||
|
{ "tf_power", &type_float, &dst->tf_power, PARAMS_GROUP_TF_POWER },
|
||||||
|
{ "min_lum", &type_float, &dst->prim_lum[0], PARAMS_GROUP_LUMINANCE },
|
||||||
|
{ "max_lum", &type_float, &dst->prim_lum[1], PARAMS_GROUP_LUMINANCE },
|
||||||
|
{ "ref_lum", &type_float, &dst->ref_lum, PARAMS_GROUP_LUMINANCE },
|
||||||
|
{ "target_red", &type_ciexy, &dst->target_prim.primary[0], PARAMS_GROUP_TARGET_PRIMARIES },
|
||||||
|
{ "target_green", &type_ciexy, &dst->target_prim.primary[1], PARAMS_GROUP_TARGET_PRIMARIES },
|
||||||
|
{ "target_blue", &type_ciexy, &dst->target_prim.primary[2], PARAMS_GROUP_TARGET_PRIMARIES },
|
||||||
|
{ "target_white", &type_ciexy, &dst->target_prim.white_point, PARAMS_GROUP_TARGET_PRIMARIES },
|
||||||
|
{ "target_named", &type_prims, &dst->target_named, PARAMS_GROUP_TARGET_PRIMARIES_NAMED },
|
||||||
|
{ "target_min_lum", &type_float, &dst->target_lum[0], PARAMS_GROUP_TARGET_LUMINANCE },
|
||||||
|
{ "target_max_lum", &type_float, &dst->target_lum[1], PARAMS_GROUP_TARGET_LUMINANCE },
|
||||||
|
{ "max_cll", &type_float, &dst->max_cll, PARAMS_GROUP_MAX_CLL },
|
||||||
|
{ "max_fall", &type_float, &dst->max_fall, PARAMS_GROUP_MAX_FALL },
|
||||||
|
};
|
||||||
|
|
||||||
|
bool success = true;
|
||||||
|
bool found[ARRAY_LENGTH(keys)] = { 0 };
|
||||||
|
uint32_t missing_group_mask = 0;
|
||||||
|
enum profile_parameter_group last_error_group;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
/* Let's parse the keys and get the values given by users. */
|
||||||
|
for (i = 0; i < ARRAY_LENGTH(keys); i++) {
|
||||||
|
const struct config_color_params_type *mytype = keys[i].type;
|
||||||
|
char *val_str = NULL;
|
||||||
|
uint32_t *data_enum;
|
||||||
|
float *data_float;
|
||||||
|
struct weston_CIExy *data_ciexy;
|
||||||
|
const struct weston_enum_map *entry;
|
||||||
|
char *err_msg;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = weston_config_section_get_string(section, keys[i].name,
|
||||||
|
&val_str, NULL);
|
||||||
|
if (ret < 0) {
|
||||||
|
/* Key not present on the ini file, not an error. */
|
||||||
|
missing_group_mask |= keys[i].group;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst->group_mask |= keys[i].group;
|
||||||
|
found[i] = true;
|
||||||
|
|
||||||
|
switch (mytype->data_type) {
|
||||||
|
case TYPE_FLOAT:
|
||||||
|
data_float = keys[i].data;
|
||||||
|
if (!parse_float_array(data_float, 1, val_str, &err_msg)) {
|
||||||
|
weston_log("%s name=%s, parsing %s: %s\n",
|
||||||
|
msgpfx, section_name, keys[i].name, err_msg);
|
||||||
|
free(err_msg);
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_CIEXY:
|
||||||
|
data_ciexy = keys[i].data;
|
||||||
|
if (!parse_CIExy(data_ciexy, val_str, &err_msg)) {
|
||||||
|
weston_log("%s name=%s, parsing %s: %s\n",
|
||||||
|
msgpfx, section_name, keys[i].name, err_msg);
|
||||||
|
free(err_msg);
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_ENUM:
|
||||||
|
data_enum = keys[i].data;
|
||||||
|
entry = weston_enum_map_find_name_(mytype->map, mytype->map_len, val_str);
|
||||||
|
if (entry) {
|
||||||
|
*data_enum = entry->value;
|
||||||
|
} else {
|
||||||
|
weston_log("%s name=%s, %s has unknown value '%s'.\n",
|
||||||
|
msgpfx, section_name, keys[i].name, val_str);
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(val_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
last_error_group = 0;
|
||||||
|
/* Ensure groups are given fully or not at all. */
|
||||||
|
for (i = 0; i < ARRAY_LENGTH(keys); i++) {
|
||||||
|
uint32_t group = keys[i].group;
|
||||||
|
|
||||||
|
if ((dst->group_mask & group) && (missing_group_mask & group)) {
|
||||||
|
success = false;
|
||||||
|
if (last_error_group == 0)
|
||||||
|
weston_log("%s name=%s:\n", msgpfx, section_name);
|
||||||
|
if (group != last_error_group) {
|
||||||
|
const struct weston_enum_map *e;
|
||||||
|
|
||||||
|
e = weston_enum_map_find_value(profile_parameter_group_names, group);
|
||||||
|
weston_assert_ptr_not_null(compositor, e);
|
||||||
|
weston_log_continue(" group: %s\n", e->name);
|
||||||
|
}
|
||||||
|
last_error_group = group;
|
||||||
|
weston_log_continue(" %s is %s.\n", keys[i].name,
|
||||||
|
found[i] ? "set" : "missing");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (last_error_group != 0)
|
||||||
|
weston_log_continue("You must set either none or all keys of a group.\n");
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
config_color_params_to_builder(struct weston_color_profile_param_builder *builder,
|
||||||
|
const struct config_color_params *params)
|
||||||
|
{
|
||||||
|
if (params->group_mask & PARAMS_GROUP_PRIMARIES) {
|
||||||
|
weston_color_profile_param_builder_set_primaries(builder,
|
||||||
|
¶ms->prim);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->group_mask & PARAMS_GROUP_PRIMARIES_NAMED) {
|
||||||
|
weston_color_profile_param_builder_set_primaries_named(builder,
|
||||||
|
params->prim_named);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->group_mask & PARAMS_GROUP_TF_POWER) {
|
||||||
|
weston_color_profile_param_builder_set_tf_power_exponent(builder,
|
||||||
|
params->tf_power);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->group_mask & PARAMS_GROUP_TF_NAMED) {
|
||||||
|
weston_color_profile_param_builder_set_tf_named(builder,
|
||||||
|
params->tf_named);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->group_mask & PARAMS_GROUP_LUMINANCE) {
|
||||||
|
weston_color_profile_param_builder_set_primary_luminance(builder,
|
||||||
|
params->ref_lum,
|
||||||
|
params->prim_lum[0],
|
||||||
|
params->prim_lum[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->group_mask & PARAMS_GROUP_TARGET_PRIMARIES) {
|
||||||
|
weston_color_profile_param_builder_set_target_primaries(builder,
|
||||||
|
¶ms->target_prim);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->group_mask & PARAMS_GROUP_TARGET_LUMINANCE) {
|
||||||
|
weston_color_profile_param_builder_set_target_luminance(builder,
|
||||||
|
params->target_lum[0],
|
||||||
|
params->target_lum[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->group_mask & PARAMS_GROUP_TARGET_PRIMARIES_NAMED) {
|
||||||
|
weston_color_profile_param_builder_set_target_primaries_named(builder,
|
||||||
|
params->target_named);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->group_mask & PARAMS_GROUP_MAX_CLL)
|
||||||
|
weston_color_profile_param_builder_set_maxCLL(builder, params->max_cll);
|
||||||
|
|
||||||
|
if (params->group_mask & PARAMS_GROUP_MAX_FALL)
|
||||||
|
weston_color_profile_param_builder_set_maxFALL(builder, params->max_fall);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct weston_color_profile *
|
||||||
|
wet_create_config_color_profile(struct weston_output *output,
|
||||||
|
struct weston_config_section *section,
|
||||||
|
const char *section_name,
|
||||||
|
const char *msgpfx)
|
||||||
|
{
|
||||||
|
struct config_color_params params = {};
|
||||||
|
struct weston_color_profile_param_builder *builder;
|
||||||
|
struct weston_color_profile *cprof = NULL;
|
||||||
|
enum weston_color_profile_param_builder_error error;
|
||||||
|
char *err_msg;
|
||||||
|
|
||||||
|
if (!config_color_params_parse(¶ms, section, section_name,
|
||||||
|
msgpfx, output->compositor)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
builder = weston_color_profile_param_builder_create(output->compositor);
|
||||||
|
config_color_params_to_builder(builder, ¶ms);
|
||||||
|
|
||||||
|
cprof = weston_color_profile_param_builder_create_color_profile(builder,
|
||||||
|
"frontend custom from ini",
|
||||||
|
&error, &err_msg);
|
||||||
|
if (!cprof) {
|
||||||
|
weston_log("%s name=%s, invalid parameter set:\n", msgpfx, section_name);
|
||||||
|
weston_log_indent_multiline(0, err_msg);
|
||||||
|
free(err_msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cprof;
|
||||||
|
}
|
||||||
|
|
||||||
static struct weston_color_profile *
|
static struct weston_color_profile *
|
||||||
wet_create_sRGB_profile(struct weston_compositor *compositor)
|
wet_create_sRGB_profile(struct weston_compositor *compositor)
|
||||||
{
|
{
|
||||||
|
|
@ -1597,16 +1949,34 @@ wet_create_output_color_profile(struct weston_output *output,
|
||||||
struct weston_config *wc,
|
struct weston_config *wc,
|
||||||
const char *prof_name)
|
const char *prof_name)
|
||||||
{
|
{
|
||||||
|
struct weston_config_section *prof_section;
|
||||||
|
static const char *msgpfx = "Config error in weston.ini [" COLOR_PROF_NAME "]";
|
||||||
|
|
||||||
if (strcmp(prof_name, "srgb:") == 0)
|
if (strcmp(prof_name, "srgb:") == 0)
|
||||||
return wet_create_sRGB_profile(output->compositor);
|
return wet_create_sRGB_profile(output->compositor);
|
||||||
|
|
||||||
if (strncmp(prof_name, "auto:", 5) == 0)
|
if (strncmp(prof_name, "auto:", 5) == 0)
|
||||||
return wet_parse_auto_profile(output, prof_name + 5);
|
return wet_parse_auto_profile(output, prof_name + 5);
|
||||||
|
|
||||||
weston_log("Config error in weston.ini, output %s, key "
|
if (strchr(prof_name, ':') != NULL) {
|
||||||
COLOR_PROF_NAME ": invalid value (%s)\n.",
|
weston_log("Config error in weston.ini, output %s, "
|
||||||
output->name, prof_name);
|
COLOR_PROF_NAME "=%s is illegal. "
|
||||||
return NULL;
|
"The ':' character is legal only for 'srgb:' and 'auto:'.\n",
|
||||||
|
output->name, prof_name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
prof_section = weston_config_get_section(wc, COLOR_PROF_NAME,
|
||||||
|
"name", prof_name);
|
||||||
|
if (!prof_section) {
|
||||||
|
weston_log("Config error in weston.ini, output %s: "
|
||||||
|
"no [" COLOR_PROF_NAME "] section with 'name=%s' found.\n",
|
||||||
|
output->name, prof_name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wet_create_config_color_profile(output, prof_section,
|
||||||
|
prof_name, msgpfx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
.\" shorthand for double quote that works everywhere.
|
.\" shorthand for double quote that works everywhere.
|
||||||
.ds q \N'34'
|
.ds q \N'34'
|
||||||
.TH weston.ini 5 "2024-08-07" "Weston @version@"
|
.TH weston.ini 5 "2025-07-29" "Weston @version@"
|
||||||
.\"---------------------------------------------------------------------
|
.\"---------------------------------------------------------------------
|
||||||
.SH NAME
|
.SH NAME
|
||||||
weston.ini \- configuration file for
|
weston.ini \- configuration file for
|
||||||
|
|
@ -602,7 +602,11 @@ wayland, and x11 backends, and for remoting and pipewire outputs. If
|
||||||
is also set, that is used instead.
|
is also set, that is used instead.
|
||||||
|
|
||||||
This key creates a parametric profile to be used as the output color profile.
|
This key creates a parametric profile to be used as the output color profile.
|
||||||
This key can use one of the special profile names that
|
The profile can be created from parameters recorded in a
|
||||||
|
.B color-profile
|
||||||
|
section by referring to it by its
|
||||||
|
.B name
|
||||||
|
value. Alternatively this key can use one of the special profile names that
|
||||||
contain a colon (:).
|
contain a colon (:).
|
||||||
|
|
||||||
The default, once implemented, will be
|
The default, once implemented, will be
|
||||||
|
|
@ -652,9 +656,16 @@ Examples:
|
||||||
.B color-profile=auto:
|
.B color-profile=auto:
|
||||||
.B color-profile=auto:edid-tf edid-dr
|
.B color-profile=auto:edid-tf edid-dr
|
||||||
.B color-profile=auto: edid-primaries
|
.B color-profile=auto: edid-primaries
|
||||||
|
.B color-profile=my-awesome-display
|
||||||
.EE
|
.EE
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
|
.IP
|
||||||
|
The last example causes Weston to read the
|
||||||
|
.B color-profile
|
||||||
|
section that has
|
||||||
|
.BR name=my-awesome-display .
|
||||||
|
|
||||||
.IP
|
.IP
|
||||||
Notably, setting
|
Notably, setting
|
||||||
|
|
||||||
|
|
@ -966,6 +977,229 @@ Display's desired maximum frame-average light level
|
||||||
.IR L \~cd/m²,
|
.IR L \~cd/m²,
|
||||||
a floating point value in the range 0.0\(en100000.0.
|
a floating point value in the range 0.0\(en100000.0.
|
||||||
.\"---------------------------------------------------------------------
|
.\"---------------------------------------------------------------------
|
||||||
|
.SH "COLOR-PROFILE SECTION"
|
||||||
|
Each
|
||||||
|
.B color-profile
|
||||||
|
section records one set of basic display color characterisation parameters.
|
||||||
|
Some parameters are collected into groups. Each group must be given either fully
|
||||||
|
or not at all. A usable section must contain at least the signaling primaries
|
||||||
|
.RB ( "Signaling primaries group" " or " prim_named )
|
||||||
|
and the transfer function
|
||||||
|
.RB ( tf_named " or " tf_power ).
|
||||||
|
.PP
|
||||||
|
Each section must be named with
|
||||||
|
.B name
|
||||||
|
key by which it can be referenced from other sections. A
|
||||||
|
.B color-profile
|
||||||
|
section is just a collection of parameter values and does nothing on its own.
|
||||||
|
It has an effect only when referenced from elsewhere.
|
||||||
|
.PP
|
||||||
|
See
|
||||||
|
.BR output " section key " color-profile .
|
||||||
|
.TP 7
|
||||||
|
.BI "name=" name
|
||||||
|
An arbitrary name for this section. You can choose any name you want as long as
|
||||||
|
it does not contain the colon
|
||||||
|
.RB ( : )
|
||||||
|
character. Names with at least one colon are reserved.
|
||||||
|
.TP 7
|
||||||
|
.BI "prim_named=" name
|
||||||
|
A standardised set of primaries and white point for signaling.
|
||||||
|
The following names are recognized:
|
||||||
|
.RS 11
|
||||||
|
.TP
|
||||||
|
.B srgb
|
||||||
|
sRGB (IEC 61966-2-1) and ITU-R BT.709
|
||||||
|
.TP
|
||||||
|
.B pal_m
|
||||||
|
PAL-M (ITU-R BT.470-6)
|
||||||
|
.TP
|
||||||
|
.B pal
|
||||||
|
PAL (ITU-R BT.470-6), ITU-R BT.601-7 625-line
|
||||||
|
.TP
|
||||||
|
.B ntsc
|
||||||
|
NTSC (SMPTE 170M-2004), ITU-R BT.601-7 525-line
|
||||||
|
.TP
|
||||||
|
.B generic_film
|
||||||
|
generic film with color filters using Illuminant C (ITU-T H.273)
|
||||||
|
.TP
|
||||||
|
.B bt2020
|
||||||
|
ITU-R BT.2020 and BT.2100
|
||||||
|
.TP
|
||||||
|
.B cie1931_xyz
|
||||||
|
CIE 1931 XYZ (ITU-T H.273)
|
||||||
|
.TP
|
||||||
|
.B dci_p3
|
||||||
|
DCI P3 (SMPTE RP 431-2)
|
||||||
|
.TP
|
||||||
|
.B display_p3
|
||||||
|
Apple Display P3, SMPTE EG 432-1
|
||||||
|
.TP
|
||||||
|
.B adobe_rgb
|
||||||
|
Adobe RGB (ISO 12640)
|
||||||
|
.RE
|
||||||
|
.IP
|
||||||
|
Mutually exclusive with the
|
||||||
|
.B Signaling primaries group
|
||||||
|
with which one can define custom primaries and white point.
|
||||||
|
.TP 7
|
||||||
|
.BI "target_named=" name
|
||||||
|
A standardised set of primaries and white point for the targeted color volume.
|
||||||
|
The same set of names are recognized as for
|
||||||
|
.BR prim_named .
|
||||||
|
.IP
|
||||||
|
Mutually exclusive with the
|
||||||
|
.B Target primaries group
|
||||||
|
with which one can define custom primaries and white point.
|
||||||
|
.TP 7
|
||||||
|
.BI "tf_named=" name
|
||||||
|
A standard transfer function or characteristic. The following names are
|
||||||
|
recognized:
|
||||||
|
.PP
|
||||||
|
.RS 11
|
||||||
|
.TP
|
||||||
|
.B bt1886
|
||||||
|
Rec. ITU-R BT.1886 display transfer characteristic.
|
||||||
|
Defaults to min_lum=0.01. ref_lum=100, max_lum=100.
|
||||||
|
.TP
|
||||||
|
.B gamma22
|
||||||
|
Assumed display gamma 2.2 transfer function.
|
||||||
|
An sRGB display (IEC 61966-2-1) uses this transfer function.
|
||||||
|
.TP
|
||||||
|
.B gamma28
|
||||||
|
Assumed display gamma 2.8 transfer function.
|
||||||
|
.TP
|
||||||
|
.B st240
|
||||||
|
SMPTE ST 240 (1999)
|
||||||
|
.TP
|
||||||
|
.B st428
|
||||||
|
SMPTE ST 428-1 (2019)
|
||||||
|
.TP
|
||||||
|
.B st2084
|
||||||
|
SMPTE ST 2084 Perceptual Quantizer (PQ) transfer characteristic.
|
||||||
|
Defaults to min_lum=0.005, ref_lum=203.
|
||||||
|
.TP
|
||||||
|
.B linear
|
||||||
|
Linear transfer function defined over all real numbers.
|
||||||
|
Normalised electrical values are equal the normalised optical values.
|
||||||
|
.TP
|
||||||
|
.B log100
|
||||||
|
Logarithmic transfer characteristic (100:1 range).
|
||||||
|
.TP
|
||||||
|
.B log316
|
||||||
|
Logarithmic transfer characteristic (100 * Sqrt(10) : 1 range).
|
||||||
|
.TP
|
||||||
|
.B xvycc
|
||||||
|
IEC 61966-2-4
|
||||||
|
.TP
|
||||||
|
.B hlg
|
||||||
|
Rec. ITU-R BT.2100 HLG transfer characteristic.
|
||||||
|
Defaults to min_lum=0.005, ref_lum=203, max_lum=1000.
|
||||||
|
.RE
|
||||||
|
.IP
|
||||||
|
Unless otherwise stated above, the default signaling luminance values are
|
||||||
|
min_lum=0.2, ref_lum=80, max_lum=80. See
|
||||||
|
.BR "Signaling luminances group" .
|
||||||
|
.IP
|
||||||
|
Mutually exclusive with
|
||||||
|
.B tf_power.
|
||||||
|
.TP 7
|
||||||
|
.BI "tf_power=" E
|
||||||
|
Mutually exclusive with
|
||||||
|
.B tf_named.
|
||||||
|
Set the transfer function as the power-law curve with the given exponent
|
||||||
|
.IR E ,
|
||||||
|
a real number in the range [1.0, 10.0].
|
||||||
|
Defaults to min_lum=0.2, ref_lum=80, max_lum=80.
|
||||||
|
.TP 7
|
||||||
|
.BI "max_fall=" L
|
||||||
|
Display's desired maximum frame-average light level
|
||||||
|
.IR L " cd/m²."
|
||||||
|
Undefined when not set.
|
||||||
|
.TP 7
|
||||||
|
.BI "max_cll=" L
|
||||||
|
Display's maximum content light level
|
||||||
|
.IR L " cd/m²."
|
||||||
|
Undefined when not set.
|
||||||
|
.SS Signaling primaries group
|
||||||
|
.TP 7
|
||||||
|
.BI "prim_red=" "x y"
|
||||||
|
.TQ
|
||||||
|
.BI "prim_green=" "x y"
|
||||||
|
.TQ
|
||||||
|
.BI "prim_blue=" "x y"
|
||||||
|
.TQ
|
||||||
|
.BI "prim_white=" "x y"
|
||||||
|
The signaling primaries group defines the primaries and the white point used
|
||||||
|
for encoding tristimulus into RGB values, also known as the primary color
|
||||||
|
volume.
|
||||||
|
.RI "The " x " and " y
|
||||||
|
are the CIE 1931 2-degree observer chromaticity coordinates. The values must be
|
||||||
|
in the range [-1.0, 2.0].
|
||||||
|
|
||||||
|
For an easier way to define standard primaries, see
|
||||||
|
.B prim_named
|
||||||
|
which is mutually exclusive with the signaling primaries group.
|
||||||
|
.SS Signaling luminances group
|
||||||
|
.TP 7
|
||||||
|
.BI "min_lum=" Lmin
|
||||||
|
.TQ
|
||||||
|
.BI "ref_lum=" Lref
|
||||||
|
.TQ
|
||||||
|
.BI "max_lum=" Lmax
|
||||||
|
.IR Lmin \(en Lmax
|
||||||
|
is the dynamic range of the display corresponding to 0%\(en100% signal levels.
|
||||||
|
For the
|
||||||
|
.B tf_named=st2084
|
||||||
|
setting the
|
||||||
|
.I Lmax
|
||||||
|
value is overwritten with 10'000 +
|
||||||
|
.IR Lmin .
|
||||||
|
.I Lref
|
||||||
|
is the reference luminance level to which all application contents are matched,
|
||||||
|
also referred to as graphics white luminance or standard dynamic range peak
|
||||||
|
luminance. All values are positive real numbers in cd/m².
|
||||||
|
.IR Lmin " can also be zero."
|
||||||
|
.IR Lmin " must be less than " Lref " and " Lmax .
|
||||||
|
|
||||||
|
When not set, the default values depend on the chosen transfer function or
|
||||||
|
characteristic.
|
||||||
|
.SS Target primaries group
|
||||||
|
.TP 7
|
||||||
|
.BI "target_red=" "x y"
|
||||||
|
.TQ
|
||||||
|
.BI "target_green=" "x y"
|
||||||
|
.TQ
|
||||||
|
.BI "target_blue=" "x y"
|
||||||
|
.TQ
|
||||||
|
.BI "target_white=" "x y"
|
||||||
|
The target color volume is similar to the Mastering Display Color Volume
|
||||||
|
(MDCV) in that any encoded stimulus outside of it has an undefined presentation.
|
||||||
|
This is particularly useful with a display that uses a wide gamut signal
|
||||||
|
encoding (e.g. BT.2020) but can only produce a subset of that color gamut.
|
||||||
|
.RI "The " x " and " y
|
||||||
|
are the CIE 1931 2-degree observer chromaticity coordinates. The values must be
|
||||||
|
in the range [-1.0, 2.0].
|
||||||
|
|
||||||
|
When not set, defaults to the primary color volume.
|
||||||
|
|
||||||
|
For an easier way to define standard targets, see
|
||||||
|
.B target_named
|
||||||
|
which is mutually exclusive with the target primaries group.
|
||||||
|
.SS Target luminances group
|
||||||
|
.TP 7
|
||||||
|
.BI "target_min_lum=" Lmin
|
||||||
|
.TQ
|
||||||
|
.BI "target_max_lum=" Lmax
|
||||||
|
Luminance range of the target color volume.
|
||||||
|
.IR Lmin " and " Lmax
|
||||||
|
are positive real numbers in cd/m².
|
||||||
|
.I Lmin
|
||||||
|
may also be zero, and it must be less than
|
||||||
|
.IR Lmax .
|
||||||
|
|
||||||
|
When not set, defaults to the signaling luminance range.
|
||||||
|
.\"---------------------------------------------------------------------
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.BR weston (1),
|
.BR weston (1),
|
||||||
.BR weston-bindings (7),
|
.BR weston-bindings (7),
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue