[FFmpeg-devel] [PATCH 09/15] avfilter/palettegen: average color in linear space

Clément Bœsch u at pkh.me
Sat Nov 5 17:26:11 EET 2022


sRGB colors are gamma encoded, averaging them naively is incorrect.
---
 libavfilter/vf_palettegen.c        | 18 ++++++++++--------
 tests/ref/fate/filter-palettegen-1 |  2 +-
 tests/ref/fate/filter-palettegen-2 |  2 +-
 3 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c
index d335ef91e6..00bc323d17 100644
--- a/libavfilter/vf_palettegen.c
+++ b/libavfilter/vf_palettegen.c
@@ -30,6 +30,7 @@
 #include "libavutil/intreadwrite.h"
 #include "avfilter.h"
 #include "internal.h"
+#include "palette.h"
 
 /* Reference a color and how much it's used */
 struct color_ref {
@@ -186,21 +187,22 @@ static int get_next_box_id_to_split(PaletteGenContext *s)
 static uint32_t get_avg_color(struct color_ref * const *refs,
                               const struct range_box *box)
 {
-    int i;
+    int i, r, g, b;
     const int n = box->len;
-    uint64_t r = 0, g = 0, b = 0, div = 0;
+    uint64_t div = 0;
+    double rf = 0.0, gf = 0.0, bf = 0.0;
 
     for (i = 0; i < n; i++) {
         const struct color_ref *ref = refs[box->start + i];
-        r += (ref->color >> 16 & 0xff) * ref->count;
-        g += (ref->color >>  8 & 0xff) * ref->count;
-        b += (ref->color       & 0xff) * ref->count;
+        rf += ff_srgb_u8_to_linear_f32(ref->color >> 16 & 0xff) * ref->count;
+        gf += ff_srgb_u8_to_linear_f32(ref->color >>  8 & 0xff) * ref->count;
+        bf += ff_srgb_u8_to_linear_f32(ref->color       & 0xff) * ref->count;
         div += ref->count;
     }
 
-    r = r / div;
-    g = g / div;
-    b = b / div;
+    r = ff_linear_f32_to_srgb_u8(rf / div);
+    g = ff_linear_f32_to_srgb_u8(gf / div);
+    b = ff_linear_f32_to_srgb_u8(bf / div);
 
     return 0xffU<<24 | r<<16 | g<<8 | b;
 }
diff --git a/tests/ref/fate/filter-palettegen-1 b/tests/ref/fate/filter-palettegen-1
index bebfd24e19..df3b714ebb 100644
--- a/tests/ref/fate/filter-palettegen-1
+++ b/tests/ref/fate/filter-palettegen-1
@@ -3,4 +3,4 @@
 #codec_id 0: rawvideo
 #dimensions 0: 16x16
 #sar 0: 1/1
-0,          0,          0,        1,     1024, 0x3395ef5a
+0,          0,          0,        1,     1024, 0x69ec37aa
diff --git a/tests/ref/fate/filter-palettegen-2 b/tests/ref/fate/filter-palettegen-2
index 9abec0fe8e..08320a8359 100644
--- a/tests/ref/fate/filter-palettegen-2
+++ b/tests/ref/fate/filter-palettegen-2
@@ -3,4 +3,4 @@
 #codec_id 0: rawvideo
 #dimensions 0: 16x16
 #sar 0: 1/1
-0,          0,          0,        1,     1024, 0x23e072c8
+0,          0,          0,        1,     1024, 0x76078b2e
-- 
2.38.1



More information about the ffmpeg-devel mailing list