Skip to content

Commit 39a76e5

Browse files
committed
filter_kernels: add Magic Kernel Sharp 2013 and 2021 scalers
The quadratic B-spline ("magic kernel") convolved with the respective discrete sharpening kernels, expressed as single continuous kernels with a support of radius 2.5 (mks2013) and 4.5 (mks2021). See https://johncostella.com/magic/ for details.
1 parent 8c67647 commit 39a76e5

5 files changed

Lines changed: 41 additions & 0 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add `mks2013` and `mks2021` (Magic Kernel Sharp) scale filters

DOCS/man/options.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5920,6 +5920,17 @@ them.
59205920
set to ``0.0`` and ``0.5`` respectively. This filter is sharper than
59215921
``mitchell``, but prone to ringing.
59225922

5923+
``mks2013``
5924+
Magic Kernel Sharp 2013. The quadratic B-spline ("magic kernel")
5925+
combined with a sharpening step, expressed as a single kernel with a
5926+
support of radius 2.5. See https://johncostella.com/magic/ for details.
5927+
5928+
``mks2021``
5929+
Magic Kernel Sharp 2021. A refinement of ``mks2013`` with a flatter
5930+
frequency response (support of radius 4.5), making it closer to true
5931+
interpolation, at a slightly higher cost and with marginally more
5932+
ringing.
5933+
59235934
``oversample``
59245935
A version of nearest neighbour that (naively) oversamples pixels, so
59255936
that pixels overlapping edges get linearly interpolated instead of

video/out/filter_kernels.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,28 @@ static double spline64(params *p, double x)
319319
}
320320
}
321321

322+
// Magic Kernel Sharp family: the quadratic B-spline ("magic kernel")
323+
// See https://johncostella.com/magic/
324+
static double mks2013(params *p, double x)
325+
{
326+
// quadric(x) convolved with {-1/4, +3/2, -1/4}
327+
if (x < 0.5)
328+
return 17.0/16.0 - 7.0/4.0 * (x * x);
329+
if (x < 1.5)
330+
return (x * x) - 11.0/4.0 * x + 7.0/4.0;
331+
if (x < 2.5) {
332+
x -= 5.0/2.0;
333+
return -1.0/8.0 * (x * x);
334+
}
335+
return 0.0;
336+
}
337+
338+
static double mks2021(params *p, double x)
339+
{
340+
return (mks2013(p, fabs(x - 2.0)) + 34.0 * mks2013(p, x) +
341+
mks2013(p, x + 2.0)) / 36.0;
342+
}
343+
322344
static double gaussian(params *p, double x)
323345
{
324346
return exp(-2.0 * x * x / p->params[0]);
@@ -420,6 +442,9 @@ const struct filter_kernel mp_filter_kernels[] = {
420442
{{SCALER_EWA_ROBIDOUXSHARP, 2,cubic_bc,
421443
.params = {6 / (13 + 7 * M_SQRT2), 7 / (2 + 12 * M_SQRT2)}},
422444
.polar = true},
445+
// Magic Kernel Sharp filters, see https://johncostella.com/magic/
446+
{{SCALER_MKS2013, 2.5, mks2013}},
447+
{{SCALER_MKS2021, 4.5, mks2021}},
423448
// Miscellaneous filters
424449
{{SCALER_BOX, 1, box, .resizable = true}},
425450
{{SCALER_NEAREST, 0.5, box}},

video/out/filter_kernels.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ enum scaler_filter {
4242
SCALER_ROBIDOUXSHARP,
4343
SCALER_EWA_ROBIDOUX,
4444
SCALER_EWA_ROBIDOUXSHARP,
45+
SCALER_MKS2013,
46+
SCALER_MKS2021,
4547
SCALER_BOX,
4648
SCALER_NEAREST,
4749
SCALER_TRIANGLE,

video/out/gpu/video.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,8 @@ struct gl_video {
298298
{"mitchell", SCALER_MITCHELL}, \
299299
{"robidoux", SCALER_ROBIDOUX}, \
300300
{"robidouxsharp", SCALER_ROBIDOUXSHARP}, \
301+
{"mks2013", SCALER_MKS2013}, \
302+
{"mks2021", SCALER_MKS2021}, \
301303
{"box", SCALER_BOX}, \
302304
{"nearest", SCALER_NEAREST}, \
303305
{"triangle", SCALER_TRIANGLE}, \

0 commit comments

Comments
 (0)