summaryrefslogtreecommitdiff
path: root/libavfilter/vf_lut3d.c
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2021-01-27 18:44:25 +0100
committerPaul B Mahol <onemda@gmail.com>2021-01-29 23:41:07 +0100
commit50dd020f04f73378a2a13ab2f23de0b791ebe079 (patch)
treed32efde705ae6f2fbc3e6f788b41b2f9c38711bf /libavfilter/vf_lut3d.c
parent26a53519dc82053573740430f6f0313125d36729 (diff)
avfilter/vf_lut3d: add prism interpolation
Diffstat (limited to 'libavfilter/vf_lut3d.c')
-rw-r--r--libavfilter/vf_lut3d.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/libavfilter/vf_lut3d.c b/libavfilter/vf_lut3d.c
index 12eb15fe67..fb33c93c34 100644
--- a/libavfilter/vf_lut3d.c
+++ b/libavfilter/vf_lut3d.c
@@ -50,6 +50,7 @@ enum interp_mode {
INTERPOLATE_TRILINEAR,
INTERPOLATE_TETRAHEDRAL,
INTERPOLATE_PYRAMID,
+ INTERPOLATE_PRISM,
NB_INTERP_MODE
};
@@ -105,6 +106,7 @@ typedef struct ThreadData {
{ "trilinear", "interpolate values using the 8 points defining a cube", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_TRILINEAR}, INT_MIN, INT_MAX, FLAGS, "interp_mode" }, \
{ "tetrahedral", "interpolate values using a tetrahedron", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_TETRAHEDRAL}, INT_MIN, INT_MAX, FLAGS, "interp_mode" }, \
{ "pyramid", "interpolate values using a pyramid", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_PYRAMID}, INT_MIN, INT_MAX, FLAGS, "interp_mode" }, \
+ { "prism", "interpolate values using a prism", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_PRISM}, INT_MIN, INT_MAX, FLAGS, "interp_mode" }, \
{ NULL }
#define EXPONENT_MASK 0x7F800000
@@ -237,6 +239,51 @@ static inline struct rgbvec interp_pyramid(const LUT3DContext *lut3d,
return c;
}
+static inline struct rgbvec interp_prism(const LUT3DContext *lut3d,
+ const struct rgbvec *s)
+{
+ const int lutsize2 = lut3d->lutsize2;
+ const int lutsize = lut3d->lutsize;
+ const int prev[] = {PREV(s->r), PREV(s->g), PREV(s->b)};
+ const int next[] = {NEXT(s->r), NEXT(s->g), NEXT(s->b)};
+ const struct rgbvec d = {s->r - prev[0], s->g - prev[1], s->b - prev[2]};
+ const struct rgbvec c000 = lut3d->lut[prev[0] * lutsize2 + prev[1] * lutsize + prev[2]];
+ const struct rgbvec c010 = lut3d->lut[prev[0] * lutsize2 + next[1] * lutsize + prev[2]];
+ const struct rgbvec c101 = lut3d->lut[next[0] * lutsize2 + prev[1] * lutsize + next[2]];
+ const struct rgbvec c111 = lut3d->lut[next[0] * lutsize2 + next[1] * lutsize + next[2]];
+ struct rgbvec c;
+
+ if (d.b > d.r) {
+ const struct rgbvec c001 = lut3d->lut[prev[0] * lutsize2 + prev[1] * lutsize + next[2]];
+ const struct rgbvec c011 = lut3d->lut[prev[0] * lutsize2 + next[1] * lutsize + next[2]];
+
+ c.r = c000.r + (c001.r - c000.r) * d.b + (c101.r - c001.r) * d.r + (c010.r - c000.r) * d.g +
+ (c000.r - c010.r - c001.r + c011.r) * d.b * d.g +
+ (c001.r - c011.r - c101.r + c111.r) * d.r * d.g;
+ c.g = c000.g + (c001.g - c000.g) * d.b + (c101.g - c001.g) * d.r + (c010.g - c000.g) * d.g +
+ (c000.g - c010.g - c001.g + c011.g) * d.b * d.g +
+ (c001.g - c011.g - c101.g + c111.g) * d.r * d.g;
+ c.b = c000.b + (c001.b - c000.b) * d.b + (c101.b - c001.b) * d.r + (c010.b - c000.b) * d.g +
+ (c000.b - c010.b - c001.b + c011.b) * d.b * d.g +
+ (c001.b - c011.b - c101.b + c111.b) * d.r * d.g;
+ } else {
+ const struct rgbvec c110 = lut3d->lut[next[0] * lutsize2 + next[1] * lutsize + prev[2]];
+ const struct rgbvec c100 = lut3d->lut[next[0] * lutsize2 + prev[1] * lutsize + prev[2]];
+
+ c.r = c000.r + (c101.r - c100.r) * d.b + (c100.r - c000.r) * d.r + (c010.r - c000.r) * d.g +
+ (c100.r - c110.r - c101.r + c111.r) * d.b * d.g +
+ (c000.r - c010.r - c100.r + c110.r) * d.r * d.g;
+ c.g = c000.g + (c101.g - c100.g) * d.b + (c100.g - c000.g) * d.r + (c010.g - c000.g) * d.g +
+ (c100.g - c110.g - c101.g + c111.g) * d.b * d.g +
+ (c000.g - c010.g - c100.g + c110.g) * d.r * d.g;
+ c.b = c000.b + (c101.b - c100.b) * d.b + (c100.b - c000.b) * d.r + (c010.b - c000.b) * d.g +
+ (c100.b - c110.b - c101.b + c111.b) * d.b * d.g +
+ (c000.b - c010.b - c100.b + c110.b) * d.r * d.g;
+ }
+
+ return c;
+}
+
/**
* Tetrahedral interpolation. Based on code found in Truelight Software Library paper.
* @see http://www.filmlight.ltd.uk/pdf/whitepapers/FL-TL-TN-0057-SoftwareLib.pdf
@@ -390,31 +437,37 @@ DEFINE_INTERP_FUNC_PLANAR(nearest, 8, 8)
DEFINE_INTERP_FUNC_PLANAR(trilinear, 8, 8)
DEFINE_INTERP_FUNC_PLANAR(tetrahedral, 8, 8)
DEFINE_INTERP_FUNC_PLANAR(pyramid, 8, 8)
+DEFINE_INTERP_FUNC_PLANAR(prism, 8, 8)
DEFINE_INTERP_FUNC_PLANAR(nearest, 16, 9)
DEFINE_INTERP_FUNC_PLANAR(trilinear, 16, 9)
DEFINE_INTERP_FUNC_PLANAR(tetrahedral, 16, 9)
DEFINE_INTERP_FUNC_PLANAR(pyramid, 16, 9)
+DEFINE_INTERP_FUNC_PLANAR(prism, 16, 9)
DEFINE_INTERP_FUNC_PLANAR(nearest, 16, 10)
DEFINE_INTERP_FUNC_PLANAR(trilinear, 16, 10)
DEFINE_INTERP_FUNC_PLANAR(tetrahedral, 16, 10)
DEFINE_INTERP_FUNC_PLANAR(pyramid, 16, 10)
+DEFINE_INTERP_FUNC_PLANAR(prism, 16, 10)
DEFINE_INTERP_FUNC_PLANAR(nearest, 16, 12)
DEFINE_INTERP_FUNC_PLANAR(trilinear, 16, 12)
DEFINE_INTERP_FUNC_PLANAR(tetrahedral, 16, 12)
DEFINE_INTERP_FUNC_PLANAR(pyramid, 16, 12)
+DEFINE_INTERP_FUNC_PLANAR(prism, 16, 12)
DEFINE_INTERP_FUNC_PLANAR(nearest, 16, 14)
DEFINE_INTERP_FUNC_PLANAR(trilinear, 16, 14)
DEFINE_INTERP_FUNC_PLANAR(tetrahedral, 16, 14)
DEFINE_INTERP_FUNC_PLANAR(pyramid, 16, 14)
+DEFINE_INTERP_FUNC_PLANAR(prism, 16, 14)
DEFINE_INTERP_FUNC_PLANAR(nearest, 16, 16)
DEFINE_INTERP_FUNC_PLANAR(trilinear, 16, 16)
DEFINE_INTERP_FUNC_PLANAR(tetrahedral, 16, 16)
DEFINE_INTERP_FUNC_PLANAR(pyramid, 16, 16)
+DEFINE_INTERP_FUNC_PLANAR(prism, 16, 16)
#define DEFINE_INTERP_FUNC_PLANAR_FLOAT(name, depth) \
static int interp_##name##_pf##depth(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
@@ -481,6 +534,7 @@ DEFINE_INTERP_FUNC_PLANAR_FLOAT(nearest, 32)
DEFINE_INTERP_FUNC_PLANAR_FLOAT(trilinear, 32)
DEFINE_INTERP_FUNC_PLANAR_FLOAT(tetrahedral, 32)
DEFINE_INTERP_FUNC_PLANAR_FLOAT(pyramid, 32)
+DEFINE_INTERP_FUNC_PLANAR_FLOAT(prism, 32)
#define DEFINE_INTERP_FUNC(name, nbits) \
static int interp_##nbits##_##name(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
@@ -535,11 +589,13 @@ DEFINE_INTERP_FUNC(nearest, 8)
DEFINE_INTERP_FUNC(trilinear, 8)
DEFINE_INTERP_FUNC(tetrahedral, 8)
DEFINE_INTERP_FUNC(pyramid, 8)
+DEFINE_INTERP_FUNC(prism, 8)
DEFINE_INTERP_FUNC(nearest, 16)
DEFINE_INTERP_FUNC(trilinear, 16)
DEFINE_INTERP_FUNC(tetrahedral, 16)
DEFINE_INTERP_FUNC(pyramid, 16)
+DEFINE_INTERP_FUNC(prism, 16)
#define MAX_LINE_SIZE 512
@@ -1148,6 +1204,7 @@ static int config_input(AVFilterLink *inlink)
case INTERPOLATE_TRILINEAR: SET_FUNC(trilinear); break;
case INTERPOLATE_TETRAHEDRAL: SET_FUNC(tetrahedral); break;
case INTERPOLATE_PYRAMID: SET_FUNC(pyramid); break;
+ case INTERPOLATE_PRISM: SET_FUNC(prism); break;
default:
av_assert0(0);
}