diff mbox series

[FFmpeg-devel,02/15] avfilter: add palette utils

Message ID 20221105152617.1809282-3-u@pkh.me
State New
Headers show
Series [FFmpeg-devel,01/15] Revert "avfilter/vf_palette(gen|use): support palettes with alpha" | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Clément Bœsch Nov. 5, 2022, 3:26 p.m. UTC
These color management helpers will be shared by palettegen and
paletteuse in the following commits.

Note that it probably makes sense to share at least the sRGB/linear
functions with other filters at some point.
---
 libavfilter/palette.c | 101 ++++++++++++++++++++++++++++++++++++++++++
 libavfilter/palette.h |  54 ++++++++++++++++++++++
 2 files changed, 155 insertions(+)
 create mode 100644 libavfilter/palette.c
 create mode 100644 libavfilter/palette.h
diff mbox series

Patch

diff --git a/libavfilter/palette.c b/libavfilter/palette.c
new file mode 100644
index 0000000000..80514c436b
--- /dev/null
+++ b/libavfilter/palette.c
@@ -0,0 +1,101 @@ 
+/*
+ * Copyright (c) 2020 Björn Ottosson
+ * Copyright (c) 2022 Clément Bœsch <u pkh me>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <math.h>
+
+#include "libavutil/common.h"
+#include "palette.h"
+
+/**
+ * Table mapping formula:
+ *   f(x) = x < 0.04045 ? x/12.92 : ((x+.055)/(1+.055))^2.4
+ * Where x is the normalized index in the table.
+ */
+static const float srgb2linear[256] = {
+    0.000000, 0.000304, 0.000607, 0.000911, 0.001214, 0.001518, 0.001821, 0.002125,
+    0.002428, 0.002732, 0.003035, 0.003347, 0.003677, 0.004025, 0.004391, 0.004777,
+    0.005182, 0.005605, 0.006049, 0.006512, 0.006995, 0.007499, 0.008023, 0.008568,
+    0.009134, 0.009721, 0.010330, 0.010960, 0.011612, 0.012286, 0.012983, 0.013702,
+    0.014444, 0.015209, 0.015996, 0.016807, 0.017642, 0.018500, 0.019382, 0.020289,
+    0.021219, 0.022174, 0.023153, 0.024158, 0.025187, 0.026241, 0.027321, 0.028426,
+    0.029557, 0.030713, 0.031896, 0.033105, 0.034340, 0.035601, 0.036889, 0.038204,
+    0.039546, 0.040915, 0.042311, 0.043735, 0.045186, 0.046665, 0.048172, 0.049707,
+    0.051269, 0.052861, 0.054480, 0.056128, 0.057805, 0.059511, 0.061246, 0.063010,
+    0.064803, 0.066626, 0.068478, 0.070360, 0.072272, 0.074214, 0.076185, 0.078187,
+    0.080220, 0.082283, 0.084376, 0.086500, 0.088656, 0.090842, 0.093059, 0.095307,
+    0.097587, 0.099899, 0.102242, 0.104616, 0.107023, 0.109462, 0.111932, 0.114435,
+    0.116971, 0.119538, 0.122139, 0.124772, 0.127438, 0.130136, 0.132868, 0.135633,
+    0.138432, 0.141263, 0.144128, 0.147027, 0.149960, 0.152926, 0.155926, 0.158961,
+    0.162029, 0.165132, 0.168269, 0.171441, 0.174647, 0.177888, 0.181164, 0.184475,
+    0.187821, 0.191202, 0.194618, 0.198069, 0.201556, 0.205079, 0.208637, 0.212231,
+    0.215861, 0.219526, 0.223228, 0.226966, 0.230740, 0.234551, 0.238398, 0.242281,
+    0.246201, 0.250158, 0.254152, 0.258183, 0.262251, 0.266356, 0.270498, 0.274677,
+    0.278894, 0.283149, 0.287441, 0.291771, 0.296138, 0.300544, 0.304987, 0.309469,
+    0.313989, 0.318547, 0.323143, 0.327778, 0.332452, 0.337164, 0.341914, 0.346704,
+    0.351533, 0.356400, 0.361307, 0.366253, 0.371238, 0.376262, 0.381326, 0.386429,
+    0.391572, 0.396755, 0.401978, 0.407240, 0.412543, 0.417885, 0.423268, 0.428690,
+    0.434154, 0.439657, 0.445201, 0.450786, 0.456411, 0.462077, 0.467784, 0.473531,
+    0.479320, 0.485150, 0.491021, 0.496933, 0.502886, 0.508881, 0.514918, 0.520996,
+    0.527115, 0.533276, 0.539479, 0.545724, 0.552011, 0.558340, 0.564712, 0.571125,
+    0.577580, 0.584078, 0.590619, 0.597202, 0.603827, 0.610496, 0.617207, 0.623960,
+    0.630757, 0.637597, 0.644480, 0.651406, 0.658375, 0.665387, 0.672443, 0.679542,
+    0.686685, 0.693872, 0.701102, 0.708376, 0.715694, 0.723055, 0.730461, 0.737910,
+    0.745404, 0.752942, 0.760525, 0.768151, 0.775822, 0.783538, 0.791298, 0.799103,
+    0.806952, 0.814847, 0.822786, 0.830770, 0.838799, 0.846873, 0.854993, 0.863157,
+    0.871367, 0.879622, 0.887923, 0.896269, 0.904661, 0.913099, 0.921582, 0.930111,
+    0.938686, 0.947307, 0.955973, 0.964686, 0.973445, 0.982251, 0.991102, 1.000000,
+};
+
+float ff_srgb_u8_to_linear_f32(uint8_t x)
+{
+    return srgb2linear[x];
+}
+
+uint8_t ff_linear_f32_to_srgb_u8(float x)
+{
+    const float v = x < 0.0031308f ? x * 12.92f : powf(1.055f * x, 1.f/2.4f) - 0.055f;
+    return av_clip_uint8(lrintf(v * 255.f));
+}
+
+struct Lab ff_srgb_u8_to_oklab(uint32_t srgb)
+{
+    const float r = srgb2linear[srgb >> 16 & 0xff];
+    const float g = srgb2linear[srgb >>  8 & 0xff];
+    const float b = srgb2linear[srgb       & 0xff];
+
+    const float l = 0.4122214708f * r + 0.5363325363f * g + 0.0514459929f * b;
+    const float m = 0.2119034982f * r + 0.6806995451f * g + 0.1073969566f * b;
+    const float s = 0.0883024619f * r + 0.2817188376f * g + 0.6299787005f * b;
+
+    const float l_ = cbrtf(l);
+    const float m_ = cbrtf(m);
+    const float s_ = cbrtf(s);
+
+    const struct Lab ret = {
+        .L = 0.2104542553f * l_ + 0.7936177850f * m_ - 0.0040720468f * s_,
+        .a = 1.9779984951f * l_ - 2.4285922050f * m_ + 0.4505937099f * s_,
+        .b = 0.0259040371f * l_ + 0.7827717662f * m_ - 0.8086757660f * s_,
+    };
+
+    return ret;
+}
diff --git a/libavfilter/palette.h b/libavfilter/palette.h
new file mode 100644
index 0000000000..2c1c609ba2
--- /dev/null
+++ b/libavfilter/palette.h
@@ -0,0 +1,54 @@ 
+/*
+ * Copyright (c) 2020 Björn Ottosson
+ * Copyright (c) 2022 Clément Bœsch <u pkh me>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef AVFILTER_PALETTE_H
+#define AVFILTER_PALETTE_H
+
+#include <math.h>
+#include <stdint.h>
+
+#include "libavutil/attributes.h"
+
+struct Lab {
+    float L, a, b;
+};
+
+/**
+ * Map sRGB 8-bit color component to linear float value (gamma expand from
+ * electrical to optical value).
+ */
+float ff_srgb_u8_to_linear_f32(uint8_t x);
+
+/**
+ * Map a linear float value to a sRGB 8-bit color component (gamma compressed
+ * from optical to electrical value).
+ */
+uint8_t ff_linear_f32_to_srgb_u8(float x);
+
+/**
+ * sRGB (non-linear) to OkLab conversion
+ * @see https://bottosson.github.io/posts/oklab/
+ */
+struct Lab ff_srgb_u8_to_oklab(uint32_t srgb);
+
+#endif /* AVFILTER_PALETTE_H */