Skip to content

Commit b430b02

Browse files
author
drhead
committed
Add support for Magic Kernel Sharp 2021 resampling
1 parent b965116 commit b430b02

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

src/PIL/Image.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ class Resampling(IntEnum):
169169
HAMMING = 5
170170
BICUBIC = 3
171171
LANCZOS = 1
172+
MKS2021 = 6
172173

173174

174175
_filters_support = {
@@ -177,6 +178,7 @@ class Resampling(IntEnum):
177178
Resampling.HAMMING: 1.0,
178179
Resampling.BICUBIC: 2.0,
179180
Resampling.LANCZOS: 3.0,
181+
Resampling.MKS2021: 4.5,
180182
}
181183

182184

@@ -2242,6 +2244,7 @@ def resize(
22422244
Resampling.LANCZOS,
22432245
Resampling.BOX,
22442246
Resampling.HAMMING,
2247+
Resampling.MKS2021,
22452248
):
22462249
msg = f"Unknown resampling filter ({resample})."
22472250

@@ -2254,6 +2257,7 @@ def resize(
22542257
(Resampling.BICUBIC, "Image.Resampling.BICUBIC"),
22552258
(Resampling.BOX, "Image.Resampling.BOX"),
22562259
(Resampling.HAMMING, "Image.Resampling.HAMMING"),
2260+
(Resampling.MKS2021, "Image.Resampling.MKS2021"),
22572261
)
22582262
]
22592263
msg += f" Use {', '.join(filters[:-1])} or {filters[-1]}"
@@ -2904,11 +2908,12 @@ def __transformer(
29042908
Resampling.BILINEAR,
29052909
Resampling.BICUBIC,
29062910
):
2907-
if resample in (Resampling.BOX, Resampling.HAMMING, Resampling.LANCZOS):
2911+
if resample in (Resampling.BOX, Resampling.HAMMING, Resampling.LANCZOS, Resampling.MKS2021):
29082912
unusable: dict[int, str] = {
29092913
Resampling.BOX: "Image.Resampling.BOX",
29102914
Resampling.HAMMING: "Image.Resampling.HAMMING",
29112915
Resampling.LANCZOS: "Image.Resampling.LANCZOS",
2916+
Resampling.MKS2021: "Image.Resampling.MKS2021",
29122917
}
29132918
msg = unusable[resample] + f" ({resample}) cannot be used."
29142919
else:

src/libImaging/Imaging.h

+1
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ ImagingError_Clear(void);
269269
#define IMAGING_TRANSFORM_HAMMING 5
270270
#define IMAGING_TRANSFORM_BICUBIC 3
271271
#define IMAGING_TRANSFORM_LANCZOS 1
272+
#define IMAGING_TRANSFORM_MKS2021 6
272273

273274
typedef int (*ImagingTransformMap)(double *X, double *Y, int x, int y, void *data);
274275
typedef int (*ImagingTransformFilter)(void *out, Imaging im, double x, double y);

src/libImaging/Resample.c

+22
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,30 @@ lanczos_filter(double x) {
7979
return 0.0;
8080
}
8181

82+
static inline double
83+
mks_2021_filter(double x) {
84+
/* https://johncostella.com/magic/ */
85+
if (x < 0.0)
86+
x = -x;
87+
if (x < 0.5)
88+
return 577.0/576.0 - 239.0/144.0 * pow(x, 2.0);
89+
if (x < 1.5)
90+
return 35.0/36.0 * (x - 1.0) * (x - 239.0/140.0);
91+
if (x < 2.5)
92+
return 1.0/6.0 * (x - 2.0) * (65.0/24.0 - x);
93+
if (x < 3.5)
94+
return 1.0/36.0 * (x - 3.0) * (x - 15.0/4.0);
95+
if (x < 4.5)
96+
return -1.0/288.0 * pow(x - 9.0/2.0, 2.0);
97+
return(0.0);
98+
}
99+
82100
static struct filter BOX = {box_filter, 0.5};
83101
static struct filter BILINEAR = {bilinear_filter, 1.0};
84102
static struct filter HAMMING = {hamming_filter, 1.0};
85103
static struct filter BICUBIC = {bicubic_filter, 2.0};
86104
static struct filter LANCZOS = {lanczos_filter, 3.0};
105+
static struct filter MKS2021 = {mks_2021_filter, 4.5};
87106

88107
/* 8 bits for result. Filter can have negative areas.
89108
In one cases the sum of the coefficients will be negative,
@@ -693,6 +712,9 @@ ImagingResample(Imaging imIn, int xsize, int ysize, int filter, float box[4]) {
693712
case IMAGING_TRANSFORM_LANCZOS:
694713
filterp = &LANCZOS;
695714
break;
715+
case IMAGING_TRANSFORM_MKS2021:
716+
filterp = &MKS2021;
717+
break;
696718
default:
697719
return (Imaging)ImagingError_ValueError("unsupported resampling filter");
698720
}

0 commit comments

Comments
 (0)