aboutsummaryrefslogtreecommitdiffstats
path: root/libswscale/utils.c
diff options
context:
space:
mode:
authorNiklas Haas <git@haasn.dev>2024-12-16 14:49:39 +0100
committerNiklas Haas <git@haasn.dev>2024-12-26 20:31:36 +0100
commitaf6d52eec66961f6a502b0f2f390c12226d087cd (patch)
tree3c1cc1ddf6d21e3fa8c02be8a8f681356657c2a0 /libswscale/utils.c
parent3e6d89cd97d0ec66cc685fec048273e59b3e5958 (diff)
downloadffmpeg-af6d52eec66961f6a502b0f2f390c12226d087cd.tar.gz
swscale: use 16-bit intermediate precision for RGB/XYZ conversion
The current logic uses 12-bit linear light math, which is woefully insufficient and leads to nasty postarization artifacts. This patch simply switches the internal logic to 16-bit precision. This raises the memory requirement of these tables from 32 kB to 272 kB. All relevant FATE tests updated for improved accuracy. Fixes: #4829 Signed-off-by: Niklas Haas <git@haasn.dev> Sponsored-by: Sovereign Tech Fund
Diffstat (limited to 'libswscale/utils.c')
-rw-r--r--libswscale/utils.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/libswscale/utils.c b/libswscale/utils.c
index 80752b7fb0..5235cbed8d 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -951,7 +951,8 @@ static void fill_xyztables(SwsInternal *c)
{1689, 1464, 739},
{ 871, 2929, 296},
{ 79, 488, 3891} };
- static int16_t xyzgamma_tab[4096], rgbgamma_tab[4096], xyzgammainv_tab[4096], rgbgammainv_tab[4096];
+ static uint16_t xyzgamma_tab[4096], rgbgammainv_tab[4096];
+ static uint16_t rgbgamma_tab[65536], xyzgammainv_tab[65536];
memcpy(c->xyz2rgb_matrix, xyz2rgb_matrix, sizeof(c->xyz2rgb_matrix));
memcpy(c->rgb2xyz_matrix, rgb2xyz_matrix, sizeof(c->rgb2xyz_matrix));
@@ -960,15 +961,19 @@ static void fill_xyztables(SwsInternal *c)
c->xyzgammainv = xyzgammainv_tab;
c->rgbgammainv = rgbgammainv_tab;
- if (rgbgamma_tab[4095])
+ if (xyzgamma_tab[4095])
return;
- /* set gamma vectors */
+ /* set input gamma vectors */
for (i = 0; i < 4096; i++) {
- xyzgamma_tab[i] = lrint(pow(i / 4095.0, xyzgamma) * 4095.0);
- rgbgamma_tab[i] = lrint(pow(i / 4095.0, rgbgamma) * 4095.0);
- xyzgammainv_tab[i] = lrint(pow(i / 4095.0, xyzgammainv) * 4095.0);
- rgbgammainv_tab[i] = lrint(pow(i / 4095.0, rgbgammainv) * 4095.0);
+ xyzgamma_tab[i] = lrint(pow(i / 4095.0, xyzgamma) * 65535.0);
+ rgbgammainv_tab[i] = lrint(pow(i / 4095.0, rgbgammainv) * 65535.0);
+ }
+
+ /* set output gamma vectors */
+ for (i = 0; i < 65536; i++) {
+ rgbgamma_tab[i] = lrint(pow(i / 65535.0, rgbgamma) * 4095.0);
+ xyzgammainv_tab[i] = lrint(pow(i / 65535.0, xyzgammainv) * 4095.0);
}
}