From 3e1a3faa28c63cffc8b424911b8251e5c20c1877 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Sat, 4 Dec 2021 00:37:20 +0100 Subject: [PATCH] color-profile: Add gamma LUT generators More or less copied from gnome-settings-daemon. The look up tables are either calculated based on the VCGT (Video Card Gamma Table) and the blackbody color for a given temperature, or the blackbody color for a given temperature alone, if no VCGT is available. Part-of: --- src/backends/meta-color-profile.c | 122 ++++++++++++++++++++++++++++++ src/backends/meta-color-profile.h | 4 + 2 files changed, 126 insertions(+) diff --git a/src/backends/meta-color-profile.c b/src/backends/meta-color-profile.c index f759f2687..b844c4577 100644 --- a/src/backends/meta-color-profile.c +++ b/src/backends/meta-color-profile.c @@ -24,6 +24,7 @@ #include #include +#include #include "backends/meta-color-manager-private.h" @@ -380,3 +381,124 @@ meta_color_profile_get_brightness_profile (MetaColorProfile *color_profile) return cd_profile_get_metadata_item (color_profile->cd_profile, CD_PROFILE_METADATA_SCREEN_BRIGHTNESS); } + +static void +set_blackbody_color_for_temperature (CdColorRGB *blackbody_color, + unsigned int temperature) +{ + if (!cd_color_get_blackbody_rgb_full (temperature, + blackbody_color, + CD_COLOR_BLACKBODY_FLAG_USE_PLANCKIAN)) + { + g_warning ("Failed to get blackbody for %uK", temperature); + cd_color_rgb_set (blackbody_color, 1.0, 1.0, 1.0); + } + else + { + meta_topic (META_DEBUG_COLOR, + "Using blackbody color from %uK: %.1f, %.1f, %.1f", + temperature, + blackbody_color->R, + blackbody_color->G, + blackbody_color->B); + } +} + +static MetaGammaLut * +generate_gamma_lut_from_vcgt (MetaColorProfile *color_profile, + const cmsToneCurve **vcgt, + unsigned int temperature, + size_t lut_size) +{ + CdColorRGB blackbody_color; + MetaGammaLut *lut; + size_t i; + + meta_topic (META_DEBUG_COLOR, + "Generating %zu sized GAMMA LUT using temperature %uK and VCGT", + lut_size, temperature); + + set_blackbody_color_for_temperature (&blackbody_color, temperature); + + lut = g_new0 (MetaGammaLut, 1); + lut->size = lut_size; + lut->red = g_new0 (uint16_t, lut_size); + lut->green = g_new0 (uint16_t, lut_size); + lut->blue = g_new0 (uint16_t, lut_size); + + for (i = 0; i < lut_size; i++) + { + cmsFloat32Number in; + + in = (double) i / (double) (lut_size - 1); + lut->red[i] = + cmsEvalToneCurveFloat (vcgt[0], in) * + blackbody_color.R * (double) 0xffff; + lut->green[i] = + cmsEvalToneCurveFloat (vcgt[1], in) * + blackbody_color.G * (double) 0xffff; + lut->blue[i] = + cmsEvalToneCurveFloat (vcgt[2], in) * + blackbody_color.B * (gdouble) 0xffff; + } + + return lut; +} + +static MetaGammaLut * +generate_gamma_lut (MetaColorProfile *color_profile, + unsigned int temperature, + size_t lut_size) +{ + CdColorRGB blackbody_color; + MetaGammaLut *lut; + size_t i; + + meta_topic (META_DEBUG_COLOR, + "Generating %zu sized GAMMA LUT using temperature %uK", + lut_size, temperature); + + set_blackbody_color_for_temperature (&blackbody_color, temperature); + + lut = g_new0 (MetaGammaLut, 1); + lut->size = lut_size; + lut->red = g_new0 (uint16_t, lut_size); + lut->green = g_new0 (uint16_t, lut_size); + lut->blue = g_new0 (uint16_t, lut_size); + + for (i = 0; i < lut_size; i++) + { + uint16_t in; + + in = (i * 0xffff) / (lut->size - 1); + lut->red[i] = in * blackbody_color.R; + lut->green[i] = in * blackbody_color.G; + lut->blue[i] = in * blackbody_color.B; + } + + return lut; +} + +MetaGammaLut * +meta_color_profile_generate_gamma_lut (MetaColorProfile *color_profile, + unsigned int temperature, + size_t lut_size) +{ + cmsHPROFILE lcms_profile; + const cmsToneCurve **vcgt; + + g_return_val_if_fail (lut_size > 0, NULL); + + lcms_profile = cd_icc_get_handle (color_profile->cd_icc); + vcgt = cmsReadTag (lcms_profile, cmsSigVcgtTag); + + if (vcgt && *vcgt) + { + return generate_gamma_lut_from_vcgt (color_profile, vcgt, + temperature, lut_size); + } + else + { + return generate_gamma_lut (color_profile, temperature, lut_size); + } +} diff --git a/src/backends/meta-color-profile.h b/src/backends/meta-color-profile.h index 72c894aab..53f240029 100644 --- a/src/backends/meta-color-profile.h +++ b/src/backends/meta-color-profile.h @@ -60,4 +60,8 @@ const char * meta_color_profile_get_file_path (MetaColorProfile *color_profile); const char * meta_color_profile_get_brightness_profile (MetaColorProfile *color_profile); +MetaGammaLut * meta_color_profile_generate_gamma_lut (MetaColorProfile *color_profile, + unsigned int temperature, + size_t lut_size); + #endif /* META_COLOR_PROFILE_H */