389 lines
16 KiB
C
389 lines
16 KiB
C
/*
|
|
* Copyright 2023 Collabora, Ltd.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining
|
|
* a copy of this software and associated documentation files (the
|
|
* "Software"), to deal in the Software without restriction, including
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
* permit persons to whom the Software is furnished to do so, subject to
|
|
* the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice (including the
|
|
* next paragraph) shall be included in all copies or substantial
|
|
* portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#ifdef HAVE_LCMS
|
|
#include <lcms2.h>
|
|
#define LCMS_INTENT(x) .lcms_intent = (x)
|
|
#else
|
|
/* invalid value */
|
|
#define LCMS_INTENT(x) .lcms_intent = 0xffffffff
|
|
#endif
|
|
|
|
#include <libweston/libweston.h>
|
|
#include <color-properties.h>
|
|
#include "shared/helpers.h"
|
|
#include "shared/weston-assert.h"
|
|
|
|
#include "color-management-v1-server-protocol.h"
|
|
|
|
static const struct weston_color_feature_info color_feature_info_table[] = {
|
|
{
|
|
.feature = WESTON_COLOR_FEATURE_ICC,
|
|
.desc = "Allow clients to use the new_icc_creator request " \
|
|
"from the CM&HDR protocol extension",
|
|
.protocol_feature = XX_COLOR_MANAGER_V2_FEATURE_ICC_V2_V4,
|
|
},
|
|
{
|
|
.feature = WESTON_COLOR_FEATURE_PARAMETRIC,
|
|
.desc = "Allow clients to use the new_parametric_creator " \
|
|
"request from the CM&HDR protocol extension",
|
|
.protocol_feature = XX_COLOR_MANAGER_V2_FEATURE_PARAMETRIC,
|
|
},
|
|
{
|
|
.feature = WESTON_COLOR_FEATURE_SET_PRIMARIES,
|
|
.desc = "Allow clients to use the parametric set_primaries " \
|
|
"request from the CM&HDR protocol extension",
|
|
.protocol_feature = XX_COLOR_MANAGER_V2_FEATURE_SET_PRIMARIES,
|
|
},
|
|
{
|
|
.feature = WESTON_COLOR_FEATURE_SET_TF_POWER,
|
|
.desc = "Allow clients to use the parametric set_tf_power " \
|
|
"request from the CM&HDR protocol extension",
|
|
.protocol_feature = XX_COLOR_MANAGER_V2_FEATURE_SET_TF_POWER,
|
|
},
|
|
{
|
|
.feature = WESTON_COLOR_FEATURE_SET_MASTERING_DISPLAY_PRIMARIES,
|
|
.desc = "Allow clients to use the parametric " \
|
|
"set_mastering_display_primaries request from the " \
|
|
"CM&HDR protocol extension",
|
|
.protocol_feature = XX_COLOR_MANAGER_V2_FEATURE_SET_MASTERING_DISPLAY_PRIMARIES,
|
|
},
|
|
{
|
|
.feature = WESTON_COLOR_FEATURE_EXTENDED_TARGET_VOLUME,
|
|
.desc = "Allow clients to specify (through the CM&HDR protocol " \
|
|
"extension) target color volumes that extend outside of the" \
|
|
"primary color volume. This can only be supported when feature " \
|
|
"WESTON_COLOR_FEATURE_SET_MASTERING_DISPLAY_PRIMARIES " \
|
|
"is supported",
|
|
.protocol_feature = XX_COLOR_MANAGER_V2_FEATURE_EXTENDED_TARGET_VOLUME,
|
|
},
|
|
};
|
|
|
|
static const struct weston_render_intent_info render_intent_info_table[] = {
|
|
{
|
|
.intent = WESTON_RENDER_INTENT_PERCEPTUAL,
|
|
.desc = "Perceptual",
|
|
.protocol_intent = XX_COLOR_MANAGER_V2_RENDER_INTENT_PERCEPTUAL,
|
|
LCMS_INTENT(INTENT_PERCEPTUAL),
|
|
.bps = false,
|
|
},
|
|
{
|
|
.intent = WESTON_RENDER_INTENT_RELATIVE,
|
|
.desc = "Media-relative colorimetric",
|
|
.protocol_intent = XX_COLOR_MANAGER_V2_RENDER_INTENT_RELATIVE,
|
|
LCMS_INTENT(INTENT_RELATIVE_COLORIMETRIC),
|
|
.bps = false,
|
|
},
|
|
{
|
|
.intent = WESTON_RENDER_INTENT_SATURATION,
|
|
.desc = "Saturation",
|
|
.protocol_intent = XX_COLOR_MANAGER_V2_RENDER_INTENT_SATURATION,
|
|
LCMS_INTENT(INTENT_SATURATION),
|
|
.bps = false,
|
|
},
|
|
{
|
|
.intent = WESTON_RENDER_INTENT_ABSOLUTE,
|
|
.desc = "ICC-absolute colorimetric",
|
|
.protocol_intent = XX_COLOR_MANAGER_V2_RENDER_INTENT_ABSOLUTE,
|
|
LCMS_INTENT(INTENT_ABSOLUTE_COLORIMETRIC),
|
|
.bps = false,
|
|
},
|
|
{
|
|
.intent = WESTON_RENDER_INTENT_RELATIVE_BPC,
|
|
.desc = "Media-relative colorimetric + black point compensation",
|
|
.protocol_intent = XX_COLOR_MANAGER_V2_RENDER_INTENT_RELATIVE_BPC,
|
|
LCMS_INTENT(INTENT_RELATIVE_COLORIMETRIC),
|
|
.bps = true,
|
|
},
|
|
};
|
|
|
|
static const struct weston_color_primaries_info color_primaries_info_table[] = {
|
|
{
|
|
.primaries = WESTON_PRIMARIES_CICP_SRGB,
|
|
.desc = "Color primaries for the sRGB color space as defined by " \
|
|
"the BT.709 standard",
|
|
.protocol_primaries = XX_COLOR_MANAGER_V2_PRIMARIES_SRGB,
|
|
.color_gamut = {
|
|
.primary = { { 0.64, 0.33 }, /* RGB order */
|
|
{ 0.30, 0.60 },
|
|
{ 0.15, 0.06 },
|
|
},
|
|
.white_point = { 0.3127, 0.3290 },
|
|
},
|
|
},
|
|
{
|
|
.primaries = WESTON_PRIMARIES_CICP_PAL_M,
|
|
.desc = "Color primaries for PAL-M as defined by the BT.470 standard",
|
|
.protocol_primaries = XX_COLOR_MANAGER_V2_PRIMARIES_PAL_M,
|
|
.color_gamut = {
|
|
.primary = { { 0.67, 0.33 }, /* RGB order */
|
|
{ 0.21, 0.71 },
|
|
{ 0.14, 0.08 },
|
|
},
|
|
.white_point = { 0.3101, 0.3162 },
|
|
},
|
|
},
|
|
{
|
|
.primaries = WESTON_PRIMARIES_CICP_PAL,
|
|
.desc = "Color primaries for PAL as defined by the BT.601 standard",
|
|
.protocol_primaries = XX_COLOR_MANAGER_V2_PRIMARIES_PAL,
|
|
.color_gamut = {
|
|
.primary = { { 0.64, 0.33 }, /* RGB order */
|
|
{ 0.29, 0.60 },
|
|
{ 0.15, 0.06 },
|
|
},
|
|
.white_point = { 0.3127, 0.3290 },
|
|
},
|
|
},
|
|
{
|
|
.primaries = WESTON_PRIMARIES_CICP_NTSC,
|
|
.desc = "Color primaries for NTSC as defined by the BT.601 standard",
|
|
.protocol_primaries = XX_COLOR_MANAGER_V2_PRIMARIES_NTSC,
|
|
.color_gamut = {
|
|
.primary = { { 0.630, 0.340 }, /* RGB order */
|
|
{ 0.310, 0.595 },
|
|
{ 0.155, 0.070 },
|
|
},
|
|
.white_point = { 0.3127, 0.3290 },
|
|
},
|
|
},
|
|
{
|
|
.primaries = WESTON_PRIMARIES_CICP_GENERIC_FILM,
|
|
.desc = "Generic film with color filters using Illuminant C",
|
|
.protocol_primaries = XX_COLOR_MANAGER_V2_PRIMARIES_GENERIC_FILM,
|
|
.color_gamut = {
|
|
.primary = { { 0.681, 0.319 }, /* RGB order */
|
|
{ 0.243, 0.692 },
|
|
{ 0.145, 0.049 },
|
|
},
|
|
.white_point = { 0.3101, 0.3162 },
|
|
},
|
|
},
|
|
{
|
|
.primaries = WESTON_PRIMARIES_CICP_BT2020,
|
|
.desc = "Color primaries as defined by the BT.2020 and BT.2100 " \
|
|
"standard",
|
|
.protocol_primaries = XX_COLOR_MANAGER_V2_PRIMARIES_BT2020,
|
|
.color_gamut = {
|
|
.primary = { { 0.708, 0.292 }, /* RGB order */
|
|
{ 0.170, 0.797 },
|
|
{ 0.131, 0.046 },
|
|
},
|
|
.white_point = { 0.3127, 0.3290 },
|
|
},
|
|
},
|
|
{
|
|
.primaries = WESTON_PRIMARIES_CICP_CIE1931_XYZ,
|
|
.desc = "Color primaries of the full CIE 1931 XYZ color space",
|
|
.protocol_primaries = XX_COLOR_MANAGER_V2_PRIMARIES_CIE1931_XYZ,
|
|
.color_gamut = {
|
|
.primary = { { 1.0, 0.0 }, /* RGB order */
|
|
{ 0.0, 1.0 },
|
|
{ 0.0, 0.0 },
|
|
},
|
|
.white_point = { 0.3333, 0.3333 },
|
|
},
|
|
},
|
|
{
|
|
.primaries = WESTON_PRIMARIES_CICP_DCI_P3,
|
|
.desc = "Color primaries of the DCI P3 color space as defined by " \
|
|
"the SMPTE RP 431 standard",
|
|
.protocol_primaries = XX_COLOR_MANAGER_V2_PRIMARIES_DCI_P3,
|
|
.color_gamut = {
|
|
.primary = { { 0.680, 0.320 }, /* RGB order */
|
|
{ 0.265, 0.690 },
|
|
{ 0.150, 0.060 },
|
|
},
|
|
.white_point = { 0.314, 0.351 },
|
|
},
|
|
},
|
|
{
|
|
.primaries = WESTON_PRIMARIES_CICP_DISPLAY_P3,
|
|
.desc = "Color primaries of Display P3 variant of the DCI-P3 color " \
|
|
"space as defined by the SMPTE EG 432 standard",
|
|
.protocol_primaries = XX_COLOR_MANAGER_V2_PRIMARIES_DISPLAY_P3,
|
|
.color_gamut = {
|
|
.primary = { { 0.680, 0.320 }, /* RGB order */
|
|
{ 0.265, 0.690 },
|
|
{ 0.150, 0.060 },
|
|
},
|
|
.white_point = { 0.3127, 0.3290 },
|
|
},
|
|
},
|
|
{
|
|
.primaries = WESTON_PRIMARIES_ADOBE_RGB,
|
|
.desc = "Color primaries of the Adobe RGB color space as defined " \
|
|
"by the ISO 12640 standard",
|
|
.protocol_primaries = XX_COLOR_MANAGER_V2_PRIMARIES_ADOBE_RGB,
|
|
.color_gamut = {
|
|
.primary = { { 0.64, 0.33 }, /* RGB order */
|
|
{ 0.21, 0.71 },
|
|
{ 0.15, 0.06 },
|
|
},
|
|
.white_point = { 0.3127, 0.3290 },
|
|
},
|
|
},
|
|
};
|
|
|
|
static const struct weston_color_tf_info color_tf_info_table[] = {
|
|
{
|
|
.tf = WESTON_TF_LINEAR,
|
|
.desc = "Linear transfer function",
|
|
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_LINEAR,
|
|
},
|
|
{
|
|
.tf = WESTON_TF_GAMMA22,
|
|
.desc = "Assumed display gamma 2.2 transfer function",
|
|
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_GAMMA22,
|
|
},
|
|
{
|
|
.tf = WESTON_TF_GAMMA28,
|
|
.desc = "Assumed display gamma 2.8 transfer function",
|
|
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_GAMMA28,
|
|
},
|
|
{
|
|
.tf = WESTON_TF_SRGB,
|
|
.desc = "sRGB piece-wise transfer function",
|
|
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_SRGB,
|
|
},
|
|
{
|
|
.tf = WESTON_TF_EXT_SRGB,
|
|
.desc = "Extended sRGB piece-wise transfer function",
|
|
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_EXT_SRGB,
|
|
},
|
|
{
|
|
.tf = WESTON_TF_BT709,
|
|
.desc = "BT.709 transfer function",
|
|
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_BT709,
|
|
},
|
|
{
|
|
.tf = WESTON_TF_BT1361,
|
|
.desc = "BT.1361 extended transfer function",
|
|
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_BT1361,
|
|
},
|
|
{
|
|
.tf = WESTON_TF_ST240,
|
|
.desc = "SMPTE ST 240 transfer function",
|
|
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_ST240,
|
|
},
|
|
{
|
|
.tf = WESTON_TF_ST428,
|
|
.desc = "SMPTE ST 428 transfer function",
|
|
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_ST428,
|
|
},
|
|
{
|
|
.tf = WESTON_TF_ST2084_PQ,
|
|
.desc = "Perceptual quantizer transfer function",
|
|
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_ST2084_PQ,
|
|
},
|
|
{
|
|
.tf = WESTON_TF_LOG_100,
|
|
.desc = "Logarithmic 100:1 transfer function",
|
|
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_LOG_100,
|
|
},
|
|
{
|
|
.tf = WESTON_TF_LOG_316,
|
|
.desc = "Logarithmic (100*Sqrt(10) : 1) transfer function",
|
|
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_LOG_316,
|
|
},
|
|
{
|
|
.tf = WESTON_TF_XVYCC,
|
|
.desc = "IEC 61966-2-4 transfer function",
|
|
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_XVYCC,
|
|
},
|
|
{
|
|
.tf = WESTON_TF_HLG,
|
|
.desc = "Hybrid log-gamma transfer function",
|
|
.protocol_tf = XX_COLOR_MANAGER_V2_TRANSFER_FUNCTION_HLG,
|
|
},
|
|
};
|
|
|
|
WL_EXPORT const struct weston_color_feature_info *
|
|
weston_color_feature_info_from(struct weston_compositor *compositor,
|
|
enum weston_color_feature feature)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < ARRAY_LENGTH(color_feature_info_table); i++)
|
|
if (color_feature_info_table[i].feature == feature)
|
|
return &color_feature_info_table[i];
|
|
|
|
weston_assert_not_reached(compositor, "unknown color feature");
|
|
}
|
|
|
|
WL_EXPORT const struct weston_render_intent_info *
|
|
weston_render_intent_info_from(struct weston_compositor *compositor,
|
|
enum weston_render_intent intent)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < ARRAY_LENGTH(render_intent_info_table); i++)
|
|
if (render_intent_info_table[i].intent == intent)
|
|
return &render_intent_info_table[i];
|
|
|
|
weston_assert_not_reached(compositor, "unknown render intent");
|
|
}
|
|
|
|
WL_EXPORT const struct weston_render_intent_info *
|
|
weston_render_intent_info_from_protocol(struct weston_compositor *compositor,
|
|
uint32_t protocol_intent)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < ARRAY_LENGTH(render_intent_info_table); i++)
|
|
if (render_intent_info_table[i].protocol_intent == protocol_intent)
|
|
return &render_intent_info_table[i];
|
|
|
|
return NULL;
|
|
}
|
|
|
|
WL_EXPORT const struct weston_color_primaries_info *
|
|
weston_color_primaries_info_from(struct weston_compositor *compositor,
|
|
enum weston_color_primaries primaries)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < ARRAY_LENGTH(color_primaries_info_table); i++)
|
|
if (color_primaries_info_table[i].primaries == primaries)
|
|
return &color_primaries_info_table[i];
|
|
|
|
weston_assert_not_reached(compositor, "unknown primaries");
|
|
}
|
|
|
|
WL_EXPORT const struct weston_color_tf_info *
|
|
weston_color_tf_info_from(struct weston_compositor *compositor,
|
|
enum weston_transfer_function tf)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < ARRAY_LENGTH(color_tf_info_table); i++)
|
|
if (color_tf_info_table[i].tf == tf)
|
|
return &color_tf_info_table[i];
|
|
|
|
weston_assert_not_reached(compositor, "unknown tf");
|
|
}
|