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 --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 */ -- 2.38.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".