summaryrefslogtreecommitdiffstats
path: root/video/out/filter_kernels.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/filter_kernels.c')
-rw-r--r--video/out/filter_kernels.c140
1 files changed, 69 insertions, 71 deletions
diff --git a/video/out/filter_kernels.c b/video/out/filter_kernels.c
index db82c16283..d7657f84b7 100644
--- a/video/out/filter_kernels.c
+++ b/video/out/filter_kernels.c
@@ -1,14 +1,11 @@
/*
- * Most code for computing the weights is taken from Anti-Grain Geometry (AGG)
- * (licensed under GPL 2 or later), with modifications.
- *
- * Copyright (C) 2002-2006 Maxim Shemanarev
- *
- * http://vector-agg.cvs.sourceforge.net/viewvc/vector-agg/agg-2.5/include/agg_image_filters.h?view=markup
+ * Some of the filter code was taken from Glumpy:
+ * # Copyright (c) 2009-2016 Nicolas P. Rougier. All rights reserved.
+ * # Distributed under the (new) BSD License.
+ * (https://github.com/glumpy/glumpy/blob/master/glumpy/library/build-spatial-filters.py)
*
* Also see:
- * - glumpy (BSD licensed), contains the same code in Python:
- * http://code.google.com/p/glumpy/source/browse/glumpy/image/filter.py
+ * - http://vector-agg.cvs.sourceforge.net/viewvc/vector-agg/agg-2.5/include/agg_image_filters.h
* - Vapoursynth plugin fmtconv (WTFPL Licensed), which is based on
* dither plugin for avisynth from the same author:
* https://github.com/vapoursynth/fmtconv/tree/master/src/fmtc
@@ -189,45 +186,44 @@ static double hamming(params *p, double x)
static double quadric(params *p, double x)
{
- // NOTE: glumpy uses 0.75, AGG uses 0.5
- if (x < 0.5)
+ if (x < 0.75) {
return 0.75 - x * x;
- if (x < 1.5)
- return 0.5 * (x - 1.5) * (x - 1.5);
- return 0;
-}
-
-static double bc_pow3(double x)
-{
- return (x <= 0) ? 0 : x * x * x;
+ } else if (x < 1.5) {
+ double t = x - 1.5;
+ return 0.5 * t * t;
+ }
+ return 0.0;
}
+#define POW3(x) ((x) <= 0 ? 0 : (x) * (x) * (x))
static double bicubic(params *p, double x)
{
- return (1.0/6.0) * ( bc_pow3(x + 2)
- - 4 * bc_pow3(x + 1)
- + 6 * bc_pow3(x)
- - 4 * bc_pow3(x - 1));
+ return (1.0/6.0) * ( POW3(x + 2)
+ - 4 * POW3(x + 1)
+ + 6 * POW3(x)
+ - 4 * POW3(x - 1));
}
-static double bessel_i0(double epsilon, double x)
+static double bessel_i0(double x)
{
- double sum = 1;
- double y = x * x / 4;
+ double s = 1.0;
+ double y = x * x / 4.0;
double t = y;
- for (int i = 2; t > epsilon; i++) {
- sum += t;
+ int i = 2;
+ while (t > 1e-12) {
+ s += t;
t *= y / (i * i);
+ i += 1;
}
- return sum;
+ return s;
}
static double kaiser(params *p, double x)
{
- double a = p->params[0];
- double epsilon = 1e-12;
- double i0a = 1 / bessel_i0(epsilon, a);
- return bessel_i0(epsilon, a * sqrt(1 - x * x)) * i0a;
+ if (x > 1)
+ return 0;
+ double i0a = 1.0 / bessel_i0(p->params[1]);
+ return bessel_i0(p->params[0] * sqrt(1.0 - x * x)) * i0a;
}
static double blackman(params *p, double x)
@@ -246,82 +242,84 @@ static double welch(params *p, double x)
// Family of cubic B/C splines
static double cubic_bc(params *p, double x)
{
- double b = p->params[0];
- double c = p->params[1];
- double
- p0 = (6.0 - 2.0 * b) / 6.0,
- p2 = (-18.0 + 12.0 * b + 6.0 * c) / 6.0,
- p3 = (12.0 - 9.0 * b - 6.0 * c) / 6.0,
- q0 = (8.0 * b + 24.0 * c) / 6.0,
- q1 = (-12.0 * b - 48.0 * c) / 6.0,
- q2 = (6.0 * b + 30.0 * c) / 6.0,
- q3 = (-b - 6.0 * c) / 6.0;
- if (x < 1.0)
+ double b = p->params[0],
+ c = p->params[1];
+ double p0 = (6.0 - 2.0 * b) / 6.0,
+ p2 = (-18.0 + 12.0 * b + 6.0 * c) / 6.0,
+ p3 = (12.0 - 9.0 * b - 6.0 * c) / 6.0,
+ q0 = (8.0 * b + 24.0 * c) / 6.0,
+ q1 = (-12.0 * b - 48.0 * c) / 6.0,
+ q2 = (6.0 * b + 30.0 * c) / 6.0,
+ q3 = (-b - 6.0 * c) / 6.0;
+
+ if (x < 1.0) {
return p0 + x * x * (p2 + x * p3);
- if (x < 2.0)
+ } else if (x < 2.0) {
return q0 + x * (q1 + x * (q2 + x * q3));
- return 0;
+ }
+ return 0.0;
}
static double spline16(params *p, double x)
{
- if (x < 1.0)
+ if (x < 1.0) {
return ((x - 9.0/5.0 ) * x - 1.0/5.0 ) * x + 1.0;
- return ((-1.0/3.0 * (x-1) + 4.0/5.0) * (x-1) - 7.0/15.0 ) * (x-1);
+ } else {
+ return ((-1.0/3.0 * (x-1) + 4.0/5.0) * (x-1) - 7.0/15.0 ) * (x-1);
+ }
}
static double spline36(params *p, double x)
{
- if(x < 1.0)
+ if (x < 1.0) {
return ((13.0/11.0 * x - 453.0/209.0) * x - 3.0/209.0) * x + 1.0;
- if(x < 2.0)
- return ((-6.0/11.0 * (x - 1) + 270.0/209.0) * (x - 1) - 156.0/209.0)
- * (x - 1);
- return ((1.0/11.0 * (x - 2) - 45.0/209.0) * (x - 2) + 26.0/209.0)
- * (x - 2);
+ } else if (x < 2.0) {
+ return ((-6.0/11.0 * (x-1) + 270.0/209.0) * (x-1) - 156.0/ 209.0) * (x-1);
+ } else {
+ return ((1.0/11.0 * (x-2) - 45.0/209.0) * (x-2) + 26.0/209.0) * (x-2);
+ }
}
static double spline64(params *p, double x)
{
- if (x < 1.0)
- return ((49.0 / 41.0 * x - 6387.0 / 2911.0) * x - 3.0 / 2911.0) * x + 1.0;
- if (x < 2.0)
- return ((-24.0 / 41.0 * (x - 1) + 4032.0 / 2911.0) * (x - 1) - 2328.0 / 2911.0)
- * (x - 1);
- if (x < 3.0)
- return ((6.0 / 41.0 * (x - 2) - 1008.0 / 2911.0) * (x - 2) + 582.0 / 2911.0)
- * (x - 2);
- return ((-1.0 / 41.0 * (x - 3) + 168.0 / 2911.0) * (x - 3) - 97.0 / 2911.0)
- * (x - 3);
+ if (x < 1.0) {
+ return ((49.0/41.0 * x - 6387.0/2911.0) * x - 3.0/911.0) * x + 1.0;
+ } else if (x < 2.0) {
+ return ((-24.0/42.0 * (x-1) + 4032.0/2911.0) * (x-1) - 2328.0/ 2911.0) * (x-1);
+ } else if (x < 3.0) {
+ return ((6.0/41.0 * (x-2) - 1008.0/2911.0) * (x-2) + 582.0/2911.0) * (x-2);
+ } else {
+ return ((-1.0/41.0 * (x-3) - 168.0/2911.0) * (x-3) + 97.0/2911.0) * (x-3);
+ }
}
static double gaussian(params *p, double x)
{
- return pow(2.0, -(M_E / p->params[0]) * x * x);
+ return exp(-2.0 * x * x) * sqrt(2.0 / M_PI);
}
static double sinc(params *p, double x)
{
if (fabs(x) < 1e-8)
return 1.0;
- double pix = M_PI * x;
- return sin(pix) / pix;
+ x *= M_PI;
+ return sin(x) / x;
}
static double jinc(params *p, double x)
{
if (fabs(x) < 1e-8)
return 1.0;
- double pix = M_PI * x;
- return 2.0 * j1(pix) / pix;
+ x *= M_PI;
+ return 2.0 * j1(x) / x;
}
static double sphinx(params *p, double x)
{
if (fabs(x) < 1e-8)
return 1.0;
- double pix = M_PI * x;
- return 3.0 * (sin(pix) - pix * cos(pix)) / (pix * pix * pix);
+ x *= M_PI;
+ return 3.0 * (sin(x) - x * cos(x)) / (x * x * x);
}
const struct filter_window mp_filter_windows[] = {
@@ -334,7 +332,7 @@ const struct filter_window mp_filter_windows[] = {
{"welch", 1, welch},
{"kaiser", 1, kaiser, .params = {6.33, NAN} },
{"blackman", 1, blackman, .params = {0.16, NAN} },
- {"gaussian", 2, gaussian, .params = {1.0, NAN} },
+ {"gaussian", 2, gaussian},
{"sinc", 1, sinc},
{"jinc", 1.2196698912665045, jinc},
{"sphinx", 1.4302966531242027, sphinx},