diff --git a/CHANGELOG.md b/CHANGELOG.md index 91627d0d..f231a1be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -90,6 +90,9 @@ ### Changed * `cursor.color` moved to `colors.cursor`. +* `gamma-correct-blending=yes` now uses a pure gamma 2.2 transfer + function, instead of the piece-wise sRGB transfer function, to match + what compositors do. ### Deprecated @@ -99,6 +102,15 @@ ### Removed ### Fixed + +* Wrong colors when `gamma-correct-blending=yes` (the default when + there is compositor support). Note that some colors will still be + off by a **very** small amount, due to loss of precision when + converting to a linear color space. ([#2035][2035]). + +[2035]: https://codeberg.org/dnkl/foot/issues/2035 + + ### Security ### Contributors diff --git a/scripts/srgb.py b/scripts/srgb.py index 7655dbe4..12056956 100755 --- a/scripts/srgb.py +++ b/scripts/srgb.py @@ -5,21 +5,16 @@ import math import sys +# Note: we use a pure gamma 2.2 function, rather than the piece-wise +# sRGB transfer function, since that is what all compositors do. + def srgb_to_linear(f: float) -> float: assert(f >= 0 and f <= 1.0) - - if f <= 0.04045: - return f / 12.92 - - return math.pow((f + 0.055) / 1.055, 2.4) + return math.pow(f, 2.2) def linear_to_srgb(f: float) -> float: - if f < 0.0031308: - return f * 12.92 - - return 1.055 * math.pow(f, 1 / 2.4) - 0.055 - + return math.pow(f, 1 / 2.2) def main(): @@ -29,24 +24,10 @@ def main(): opts = parser.parse_args() linear_table: list[int] = [] - srgb_table: list[int] = [] for i in range(256): linear_table.append(int(srgb_to_linear(float(i) / 255) * 65535 + 0.5)) - for i in range(4096): - srgb_table.append(int(linear_to_srgb(float(i) / 4095) * 255 + 0.5)) - - for i in range(256): - while True: - linear = linear_table[i] - srgb = srgb_table[linear >> 4] - - if i == srgb: - break - - linear_table[i] += 1 - opts.h_output.write("#pragma once\n") opts.h_output.write("#include \n")