diff options
-rw-r--r-- | video/out/filter_kernels.c | 140 |
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}, |