scripts: srgb: use 2.2 gamma TF instead of piece-wise sRGB TF

This commit is contained in:
Daniel Eklöf 2025-04-27 10:14:45 +02:00
parent d20fbc6807
commit 97910a5cba
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 17 additions and 24 deletions

View file

@ -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

View file

@ -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 <stdint.h>\n")