icc-brightness icon indicating copy to clipboard operation
icc-brightness copied to clipboard

Alter an existing ICC profile

Open nmaggioni opened this issue 4 years ago • 1 comments

It's possible to source calibrated ICC profiles for many laptop screens, but using them on OLED panels would force the maximum brightness. Being able to dynamically generate brightness-adjusted values from such profiles would be really interesting, or maybe even pre-generating a set of per-level profiles to be used later.

For reference, notebookcheck provides a calibrated profile for my HP Spectre 13-aw0xxx.

nmaggioni avatar May 17 '20 18:05 nmaggioni

As a very naive approach, I've compared the output of xrandr --verbose | grep -E 'Gamma|Brightness' when both the default and calibrated color profiles were active:

Default (Gnome's "automatic")

Gamma: 1.0:1.0:1.0
Brightness: 1.0

Calibrated

Gamma: 1.0:1.1:0.99
Brightness: 0.95

Basing on this, I've tried to recreate the same values in create_srgb_profile. It seems that response is nonlinear, as I've had to play around with small (0.05) increments in order to get the same values as the calibrated profile.

The result isn't perfect, but it seems close enough to me for such a hackish patch:

diff --git a/icc-brightness-gen.c b/icc-brightness-gen.c
index 1baad9d..fec17c6 100644
--- a/icc-brightness-gen.c
+++ b/icc-brightness-gen.c
@@ -21,11 +21,13 @@ cmsHPROFILE create_srgb_profile(double brightness)
     cmsMLUfree(mlu);
 
     cmsContext context_id = cmsCreateContext(NULL, NULL);
-    double curve[] = {1.0, brightness, 0.0}; // gamma, a, b for (a X +b)^gamma
+    double curve1[] = {1.0,   brightness, 0.0}; // gamma, a, b for (a X +b)^gamma
+    double curve2[] = {1.05,  brightness, 0.0};
+    double curve3[] = {0.995, brightness, 0.0};
     cmsToneCurve *tone_curve[3] = {
-	    cmsBuildParametricToneCurve(context_id, 2, curve),
-	    cmsBuildParametricToneCurve(context_id, 2, curve),
-	    cmsBuildParametricToneCurve(context_id, 2, curve),
+	    cmsBuildParametricToneCurve(context_id, 2, curve1),
+	    cmsBuildParametricToneCurve(context_id, 2, curve2),
+	    cmsBuildParametricToneCurve(context_id, 2, curve3),
     };
     cmsWriteTag(hsRGB, cmsSigVcgtTag, tone_curve);
     cmsFreeToneCurve(tone_curve[0]);

The next step could be figuring out these values automatically and writing them to a config file of sorts by adding an additional action to the main Python script, so that a single command can be run to "calibrate" icc-brightness on the currently loaded color profile; something like icc-brightness load-offsets.

nmaggioni avatar May 17 '20 23:05 nmaggioni