Skip to content

Commit ec0e361

Browse files
authored
Add Magic Kernel support (#4237)
* Add Magic Kernel support * Fix range for MKS2013 * Improve readability for MKS2013 filter * Add Magic Kernel test * Update ChangeLog
1 parent d444709 commit ec0e361

File tree

6 files changed

+68
-2
lines changed

6 files changed

+68
-2
lines changed

ChangeLog

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
8.17.0
22

3+
- add Magic Kernel support [akimon658]
4+
35
8.16.1
46

57
- support multipage JXL

libvips/include/vips/resample.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ typedef enum {
4545
VIPS_KERNEL_MITCHELL,
4646
VIPS_KERNEL_LANCZOS2,
4747
VIPS_KERNEL_LANCZOS3,
48+
VIPS_KERNEL_MKS2013,
49+
VIPS_KERNEL_MKS2021,
4850
VIPS_KERNEL_LAST
4951
} VipsKernel;
5052

libvips/resample/reduce.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@
6666
* @VIPS_KERNEL_MITCHELL: Convolve with a Mitchell kernel.
6767
* @VIPS_KERNEL_LANCZOS2: Convolve with a two-lobe Lanczos kernel.
6868
* @VIPS_KERNEL_LANCZOS3: Convolve with a three-lobe Lanczos kernel.
69+
* @VIPS_KERNEL_MKS2013: Convolve with Magic Kernel Sharp 2013.
70+
* @VIPS_KERNEL_MKS2021: Convolve with Magic Kernel Sharp 2021.
6971
*
7072
* The resampling kernels vips supports. See vips_reduce(), for example.
7173
*/

libvips/resample/reduceh.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,12 @@ vips_reduce_get_points(VipsKernel kernel, double shrink)
125125
case VIPS_KERNEL_LANCZOS3:
126126
return 2 * rint(3 * shrink) + 1;
127127

128+
case VIPS_KERNEL_MKS2013:
129+
return 2 * rint(3 * shrink) + 1;
130+
131+
case VIPS_KERNEL_MKS2021:
132+
return 2 * rint(5 * shrink) + 1;
133+
128134
default:
129135
g_assert_not_reached();
130136
return 0;

libvips/resample/templates.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,48 @@ double inline filter<VIPS_KERNEL_LANCZOS3>(double x)
402402
return 0.0;
403403
}
404404

405+
template <>
406+
double inline filter<VIPS_KERNEL_MKS2013>(double x)
407+
{
408+
if (x < 0.0)
409+
x = -x;
410+
411+
if (x >= 2.5)
412+
return 0.0;
413+
414+
if (x >= 1.5)
415+
return (x - 5.0 / 2.0) * (x - 5.0 / 2.0) / -8.0;
416+
417+
if (x >= 0.5)
418+
return (4.0 * x * x - 11.0 * x + 7.0) / 4.0;
419+
420+
return 17.0 / 16.0 - 7.0 * x * x / 4.0;
421+
}
422+
423+
template <>
424+
double inline filter<VIPS_KERNEL_MKS2021>(double x)
425+
{
426+
if (x < 0.0)
427+
x = -x;
428+
429+
if (x >= 4.5)
430+
return 0.0;
431+
432+
if (x >= 3.5)
433+
return (4.0 * x * x - 36.0 * x + 81.0) / -1152.0;
434+
435+
if (x >= 2.5)
436+
return (4.0 * x * x - 27.0 * x + 45.0) / 144.0;
437+
438+
if (x >= 1.5)
439+
return (24.0 * x * x - 113.0 * x + 130.0) / -144.0;
440+
441+
if (x >= 0.5)
442+
return (140.0 * x * x - 379.0 * x + 239.0) / 144.0;
443+
444+
return 577.0 / 576.0 - 239.0 * x * x / 144.0;
445+
}
446+
405447
/* Given an x in [0,1] (we can have x == 1 when building tables),
406448
* calculate c0 .. c(@n_points), the coefficients. This is called
407449
* from the interpolator as well as from the table builder.
@@ -469,6 +511,16 @@ vips_reduce_make_mask(T *c, VipsKernel kernel, const int n_points,
469511
filter<VIPS_KERNEL_LANCZOS3>, shrink, x);
470512
break;
471513

514+
case VIPS_KERNEL_MKS2013:
515+
calculate_coefficients(c, n_points,
516+
filter<VIPS_KERNEL_MKS2013>, shrink, x);
517+
break;
518+
519+
case VIPS_KERNEL_MKS2021:
520+
calculate_coefficients(c, n_points,
521+
filter<VIPS_KERNEL_MKS2021>, shrink, x);
522+
break;
523+
472524
default:
473525
g_assert_not_reached();
474526
break;

test/test-suite/test_resample.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ def test_reduce(self):
8383
for fac in [1, 1.1, 1.5, 1.999]:
8484
for fmt in all_formats:
8585
for kernel in ["nearest", "linear",
86-
"cubic", "lanczos2", "lanczos3"]:
86+
"cubic", "lanczos2",
87+
"lanczos3", "mks2013", "mks2021"]:
8788
x = im.cast(fmt)
8889
r = x.reduce(fac, fac, kernel=kernel)
8990
d = abs(r.avg() - im.avg())
@@ -93,7 +94,8 @@ def test_reduce(self):
9394
for const in [0, 1, 2, 254, 255]:
9495
im = (pyvips.Image.black(10, 10) + const).cast("uchar")
9596
for kernel in ["nearest", "linear",
96-
"cubic", "lanczos2", "lanczos3"]:
97+
"cubic", "lanczos2",
98+
"lanczos3", "mks2013", "mks2021"]:
9799
# print "testing kernel =", kernel
98100
# print "testing const =", const
99101
shr = im.reduce(2, 2, kernel=kernel)

0 commit comments

Comments
 (0)