From 39de63da8420f3dec755a1bbfdef36f730b0bf50 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 16 Jun 2025 15:49:56 +0300 Subject: [PATCH] color-lcms: switch default sRGB profile to parametric This avoids ICC paths when no ICC profiles are explicitly used. We can simplify the profile information sending and use the generic path for the stock profile as well, no longer hard-coding the stock profile in two places. Since the stock profile creation cannot fail, we can streamline cmlcms_init() a little, too. Signed-off-by: Pekka Paalanen --- libweston/color-lcms/color-lcms.c | 10 +-- libweston/color-lcms/color-lcms.h | 2 +- libweston/color-lcms/color-profile.c | 124 +++++++-------------------- 3 files changed, 32 insertions(+), 104 deletions(-) diff --git a/libweston/color-lcms/color-lcms.c b/libweston/color-lcms/color-lcms.c index 8317febfd..3229ba08d 100644 --- a/libweston/color-lcms/color-lcms.c +++ b/libweston/color-lcms/color-lcms.c @@ -429,19 +429,13 @@ cmlcms_init(struct weston_color_manager *cm_base) cmsSetLogErrorHandlerTHR(cm->lcms_ctx, lcms_error_logger); - if (!cmlcms_create_stock_profile(cm)) { - weston_log("color-lcms: error: cmlcms_create_stock_profile failed\n"); - goto out_err; - } + cm->sRGB_profile = cmlcms_create_stock_profile(cm); + weston_log("LittleCMS %d initialized.\n", cmsGetEncodedCMMversion()); return true; out_err: - if (cm->lcms_ctx) - cmsDeleteContext(cm->lcms_ctx); - cm->lcms_ctx = NULL; - weston_log_scope_destroy(cm->transforms_scope); cm->transforms_scope = NULL; weston_log_scope_destroy(cm->optimizer_scope); diff --git a/libweston/color-lcms/color-lcms.h b/libweston/color-lcms/color-lcms.h index 0c64c5f10..56fb4ad07 100644 --- a/libweston/color-lcms/color-lcms.h +++ b/libweston/color-lcms/color-lcms.h @@ -292,7 +292,7 @@ ref_cprof(struct cmlcms_color_profile *cprof); void unref_cprof(struct cmlcms_color_profile *cprof); -bool +struct cmlcms_color_profile * cmlcms_create_stock_profile(struct weston_color_manager_lcms *cm); void diff --git a/libweston/color-lcms/color-profile.c b/libweston/color-lcms/color-profile.c index 01c0d032e..295b20bfa 100644 --- a/libweston/color-lcms/color-profile.c +++ b/libweston/color-lcms/color-profile.c @@ -558,57 +558,36 @@ make_icc_file_description(struct lcmsProfilePtr profile, * BT.709 primaries with gamma-2.2 transfer characteristic. This is the * expected sRGB display response. */ -bool +struct cmlcms_color_profile * cmlcms_create_stock_profile(struct weston_color_manager_lcms *cm) { - static const cmsCIExyY D65 = { 0.3127, 0.3290, 1.0 }; - static const cmsCIExyYTRIPLE bt709 = { - { 0.6400, 0.3300, 1.0 }, - { 0.3000, 0.6000, 1.0 }, - { 0.1500, 0.0600, 1.0 } - }; - cmsToneCurve *gamma22[3]; - struct lcmsProfilePtr profile = { NULL }; - struct cmlcms_md5_sum md5sum; + struct weston_compositor *compositor = cm->base.compositor; + struct weston_color_profile_params p = {}; + struct cmlcms_color_profile *stock; char *desc = NULL; - const char *err_msg = NULL; - gamma22[0] = gamma22[1] = gamma22[2] = cmsBuildGamma(cm->lcms_ctx, 2.2); - if (gamma22[0]) - profile.p = cmsCreateRGBProfileTHR(cm->lcms_ctx, &D65, &bt709, gamma22); - cmsFreeToneCurve(gamma22[0]); - if (!profile.p) { - weston_log("color-lcms: error: failed to create stock sRGB profile.\n"); - return false; - } - if (!cmsMD5computeID(profile.p)) { - weston_log("Failed to compute MD5 for stock sRGB profile.\n"); - goto err_close; - } + p.primaries_info = weston_color_primaries_info_from(compositor, + WESTON_PRIMARIES_CICP_SRGB); + p.primaries = p.primaries_info->color_gamut; + p.tf.info = weston_color_tf_info_from(compositor, WESTON_TF_GAMMA22); + p.reference_white_luminance = 80.0; + p.min_luminance = 0.2; + p.max_luminance = 80.0; + p.target_primaries = p.primaries; + p.target_min_luminance = p.min_luminance; + p.target_max_luminance = p.max_luminance; + p.maxCLL = -1.0f; + p.maxFALL = -1.0f; - cmsGetHeaderProfileID(profile.p, md5sum.bytes); - desc = make_icc_file_description(profile, &md5sum, "sRGB stock"); - if (!desc) - goto err_close; + str_printf(&desc, "default sRGB: %s primaries, %s transfer function", + p.primaries_info->desc, p.tf.info->desc); + abort_oom_if_null(desc); - cm->sRGB_profile = cmlcms_color_profile_alloc(cm, CMLCMS_PROFILE_TYPE_ICC, desc); - cm->sRGB_profile->icc.profile = profile; - cm->sRGB_profile->icc.md5sum = md5sum; + stock = cmlcms_color_profile_alloc(cm, CMLCMS_PROFILE_TYPE_PARAMS, desc); + *stock->params = p; + cmlcms_color_profile_register(stock); - if (!ensure_output_profile_extract(cm->sRGB_profile, cm->lcms_ctx, - cmlcms_reasonable_1D_points(), &err_msg)) - goto err_close; - - cmlcms_color_profile_register(cm->sRGB_profile); - - return true; - -err_close: - if (err_msg) - weston_log("%s\n", err_msg); - - cmlcms_color_profile_destroy(cm->sRGB_profile); - return false; + return stock; } struct weston_color_profile * @@ -749,62 +728,17 @@ bool cmlcms_send_image_desc_info(struct cm_image_desc_info *cm_image_desc_info, struct weston_color_profile *cprof_base) { - struct weston_color_manager_lcms *cm = to_cmlcms(cprof_base->cm); - struct weston_compositor *compositor = cm->base.compositor; struct cmlcms_color_profile *cprof = to_cmlcms_cprof(cprof_base); - const struct weston_color_primaries_info *primaries_info; - /** - * TODO: when we convert the stock sRGB profile to a parametric profile - * instead of an ICC one, we'll be able to change the if/else below to - * a switch/case. - */ - - if (cprof->type == CMLCMS_PROFILE_TYPE_ICC && cprof != cm->sRGB_profile) { + switch (cprof->type) { + case CMLCMS_PROFILE_TYPE_ICC: return cmlcms_send_icc_info(cm_image_desc_info, cprof); - } else { - if (cprof != cm->sRGB_profile) { - weston_cm_send_parametric_info(cm_image_desc_info, cprof->params); - return true; - } - - /* Stock sRGB color profile. TODO: when we add support for - * parametric color profiles, the stock sRGB will be crafted - * using parameters, instead of cmsCreate_sRGBProfileTHR() - * (which we currently use). So we'll get the parameters - * directly from it, instead of hardcoding as we are doing here. - * We don't get the parameters from the stock sRGB color profile - * because it is not trivial to retrieve that from LittleCMS. */ - - /* Send the H.273 ColourPrimaries code point that matches the - * Rec709 primaries and the D65 white point. */ - primaries_info = weston_color_primaries_info_from(compositor, - WESTON_PRIMARIES_CICP_SRGB); - weston_cm_send_primaries_named(cm_image_desc_info, primaries_info); - - /* These are the Rec709 primaries and D65 white point. */ - weston_cm_send_primaries(cm_image_desc_info, - &primaries_info->color_gamut); - - /* Target primaries, equal to the primary primaries. */ - weston_cm_send_target_primaries(cm_image_desc_info, - &primaries_info->color_gamut); - - /* sRGB transfer function. */ - struct weston_color_tf tf = { - .info = weston_color_tf_info_from(compositor, WESTON_TF_GAMMA22), - .params = {}, - }; - weston_cm_send_tf(cm_image_desc_info, &tf); - - /* Primary luminance, default values from the protocol. */ - weston_cm_send_luminances(cm_image_desc_info, 0.2, 80.0, 80.0); - - /* Target luminance, min/max equals primary luminance min/max. */ - weston_cm_send_target_luminances(cm_image_desc_info, 0.2, 80.0); + case CMLCMS_PROFILE_TYPE_PARAMS: + weston_cm_send_parametric_info(cm_image_desc_info, cprof->params); + return true; } - return true; + return false; } struct weston_color_profile *