mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-02-02 20:54:39 +03:00
Merge pull request #8422 from radarhere/resize_i16
This commit is contained in:
commit
c9c8d45898
|
@ -44,9 +44,19 @@ class TestImagingCoreResize:
|
||||||
self.resize(hopper("1"), (15, 12), Image.Resampling.BILINEAR)
|
self.resize(hopper("1"), (15, 12), Image.Resampling.BILINEAR)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
self.resize(hopper("P"), (15, 12), Image.Resampling.BILINEAR)
|
self.resize(hopper("P"), (15, 12), Image.Resampling.BILINEAR)
|
||||||
with pytest.raises(ValueError):
|
for mode in [
|
||||||
self.resize(hopper("I;16"), (15, 12), Image.Resampling.BILINEAR)
|
"L",
|
||||||
for mode in ["L", "I", "F", "RGB", "RGBA", "CMYK", "YCbCr"]:
|
"I",
|
||||||
|
"I;16",
|
||||||
|
"I;16L",
|
||||||
|
"I;16B",
|
||||||
|
"I;16N",
|
||||||
|
"F",
|
||||||
|
"RGB",
|
||||||
|
"RGBA",
|
||||||
|
"CMYK",
|
||||||
|
"YCbCr",
|
||||||
|
]:
|
||||||
im = hopper(mode)
|
im = hopper(mode)
|
||||||
r = self.resize(im, (15, 12), Image.Resampling.BILINEAR)
|
r = self.resize(im, (15, 12), Image.Resampling.BILINEAR)
|
||||||
assert r.mode == mode
|
assert r.mode == mode
|
||||||
|
@ -305,14 +315,14 @@ class TestImageResize:
|
||||||
im = im.resize((64, 64))
|
im = im.resize((64, 64))
|
||||||
assert im.size == (64, 64)
|
assert im.size == (64, 64)
|
||||||
|
|
||||||
@pytest.mark.parametrize("mode", ("L", "RGB", "I", "F"))
|
@pytest.mark.parametrize(
|
||||||
|
"mode", ("L", "RGB", "I", "I;16", "I;16L", "I;16B", "I;16N", "F")
|
||||||
|
)
|
||||||
def test_default_filter_bicubic(self, mode: str) -> None:
|
def test_default_filter_bicubic(self, mode: str) -> None:
|
||||||
im = hopper(mode)
|
im = hopper(mode)
|
||||||
assert im.resize((20, 20), Image.Resampling.BICUBIC) == im.resize((20, 20))
|
assert im.resize((20, 20), Image.Resampling.BICUBIC) == im.resize((20, 20))
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize("mode", ("1", "P", "BGR;15", "BGR;16"))
|
||||||
"mode", ("1", "P", "I;16", "I;16L", "I;16B", "BGR;15", "BGR;16")
|
|
||||||
)
|
|
||||||
def test_default_filter_nearest(self, mode: str) -> None:
|
def test_default_filter_nearest(self, mode: str) -> None:
|
||||||
im = hopper(mode)
|
im = hopper(mode)
|
||||||
assert im.resize((20, 20), Image.Resampling.NEAREST) == im.resize((20, 20))
|
assert im.resize((20, 20), Image.Resampling.NEAREST) == im.resize((20, 20))
|
||||||
|
|
|
@ -119,10 +119,11 @@ Specific WebP Feature Checks
|
||||||
API Changes
|
API Changes
|
||||||
===========
|
===========
|
||||||
|
|
||||||
TODO
|
Default resampling filter for I;16* image modes
|
||||||
^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
TODO
|
The default resampling filter for I;16, I;16L, I;16B and I;16N has been changed from
|
||||||
|
``Image.NEAREST`` to ``Image.BICUBIC``, to match the majority of modes.
|
||||||
|
|
||||||
API Additions
|
API Additions
|
||||||
=============
|
=============
|
||||||
|
|
|
@ -2278,8 +2278,8 @@ class Image:
|
||||||
:py:data:`Resampling.BILINEAR`, :py:data:`Resampling.HAMMING`,
|
:py:data:`Resampling.BILINEAR`, :py:data:`Resampling.HAMMING`,
|
||||||
:py:data:`Resampling.BICUBIC` or :py:data:`Resampling.LANCZOS`.
|
:py:data:`Resampling.BICUBIC` or :py:data:`Resampling.LANCZOS`.
|
||||||
If the image has mode "1" or "P", it is always set to
|
If the image has mode "1" or "P", it is always set to
|
||||||
:py:data:`Resampling.NEAREST`. If the image mode specifies a number
|
:py:data:`Resampling.NEAREST`. If the image mode is "BGR;15",
|
||||||
of bits, such as "I;16", then the default filter is
|
"BGR;16" or "BGR;24", then the default filter is
|
||||||
:py:data:`Resampling.NEAREST`. Otherwise, the default filter is
|
:py:data:`Resampling.NEAREST`. Otherwise, the default filter is
|
||||||
:py:data:`Resampling.BICUBIC`. See: :ref:`concept-filters`.
|
:py:data:`Resampling.BICUBIC`. See: :ref:`concept-filters`.
|
||||||
:param box: An optional 4-tuple of floats providing
|
:param box: An optional 4-tuple of floats providing
|
||||||
|
@ -2302,8 +2302,8 @@ class Image:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if resample is None:
|
if resample is None:
|
||||||
type_special = ";" in self.mode
|
bgr = self.mode.startswith("BGR;")
|
||||||
resample = Resampling.NEAREST if type_special else Resampling.BICUBIC
|
resample = Resampling.NEAREST if bgr else Resampling.BICUBIC
|
||||||
elif resample not in (
|
elif resample not in (
|
||||||
Resampling.NEAREST,
|
Resampling.NEAREST,
|
||||||
Resampling.BILINEAR,
|
Resampling.BILINEAR,
|
||||||
|
|
|
@ -1579,16 +1579,12 @@ _putdata(ImagingObject *self, PyObject *args) {
|
||||||
int bigendian = 0;
|
int bigendian = 0;
|
||||||
if (image->type == IMAGING_TYPE_SPECIAL) {
|
if (image->type == IMAGING_TYPE_SPECIAL) {
|
||||||
// I;16*
|
// I;16*
|
||||||
if (strcmp(image->mode, "I;16N") == 0) {
|
if (strcmp(image->mode, "I;16B") == 0
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
bigendian = 1;
|
|| strcmp(image->mode, "I;16N") == 0
|
||||||
#else
|
|
||||||
bigendian = 0;
|
|
||||||
#endif
|
#endif
|
||||||
} else if (strcmp(image->mode, "I;16B") == 0) {
|
) {
|
||||||
bigendian = 1;
|
bigendian = 1;
|
||||||
} else {
|
|
||||||
bigendian = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = x = y = 0; i < n; i++) {
|
for (i = x = y = 0; i < n; i++) {
|
||||||
|
|
|
@ -460,6 +460,83 @@ ImagingResampleVertical_8bpc(
|
||||||
ImagingSectionLeave(&cookie);
|
ImagingSectionLeave(&cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ImagingResampleHorizontal_16bpc(
|
||||||
|
Imaging imOut, Imaging imIn, int offset, int ksize, int *bounds, double *kk
|
||||||
|
) {
|
||||||
|
ImagingSectionCookie cookie;
|
||||||
|
double ss;
|
||||||
|
int xx, yy, x, xmin, xmax, ss_int;
|
||||||
|
double *k;
|
||||||
|
|
||||||
|
int bigendian = 0;
|
||||||
|
if (strcmp(imIn->mode, "I;16N") == 0
|
||||||
|
#ifdef WORDS_BIGENDIAN
|
||||||
|
|| strcmp(imIn->mode, "I;16B") == 0
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
bigendian = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImagingSectionEnter(&cookie);
|
||||||
|
for (yy = 0; yy < imOut->ysize; yy++) {
|
||||||
|
for (xx = 0; xx < imOut->xsize; xx++) {
|
||||||
|
xmin = bounds[xx * 2 + 0];
|
||||||
|
xmax = bounds[xx * 2 + 1];
|
||||||
|
k = &kk[xx * ksize];
|
||||||
|
ss = 0.0;
|
||||||
|
for (x = 0; x < xmax; x++) {
|
||||||
|
ss += (imIn->image8[yy + offset][(x + xmin) * 2 + (bigendian ? 1 : 0)] +
|
||||||
|
(imIn->image8[yy + offset][(x + xmin) * 2 + (bigendian ? 0 : 1)]
|
||||||
|
<< 8)) *
|
||||||
|
k[x];
|
||||||
|
}
|
||||||
|
ss_int = ROUND_UP(ss);
|
||||||
|
imOut->image8[yy][xx * 2 + (bigendian ? 1 : 0)] = CLIP8(ss_int % 256);
|
||||||
|
imOut->image8[yy][xx * 2 + (bigendian ? 0 : 1)] = CLIP8(ss_int >> 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImagingSectionLeave(&cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ImagingResampleVertical_16bpc(
|
||||||
|
Imaging imOut, Imaging imIn, int offset, int ksize, int *bounds, double *kk
|
||||||
|
) {
|
||||||
|
ImagingSectionCookie cookie;
|
||||||
|
double ss;
|
||||||
|
int xx, yy, y, ymin, ymax, ss_int;
|
||||||
|
double *k;
|
||||||
|
|
||||||
|
int bigendian = 0;
|
||||||
|
if (strcmp(imIn->mode, "I;16N") == 0
|
||||||
|
#ifdef WORDS_BIGENDIAN
|
||||||
|
|| strcmp(imIn->mode, "I;16B") == 0
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
bigendian = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImagingSectionEnter(&cookie);
|
||||||
|
for (yy = 0; yy < imOut->ysize; yy++) {
|
||||||
|
ymin = bounds[yy * 2 + 0];
|
||||||
|
ymax = bounds[yy * 2 + 1];
|
||||||
|
k = &kk[yy * ksize];
|
||||||
|
for (xx = 0; xx < imOut->xsize; xx++) {
|
||||||
|
ss = 0.0;
|
||||||
|
for (y = 0; y < ymax; y++) {
|
||||||
|
ss += (imIn->image8[y + ymin][xx * 2 + (bigendian ? 1 : 0)] +
|
||||||
|
(imIn->image8[y + ymin][xx * 2 + (bigendian ? 0 : 1)] << 8)) *
|
||||||
|
k[y];
|
||||||
|
}
|
||||||
|
ss_int = ROUND_UP(ss);
|
||||||
|
imOut->image8[yy][xx * 2 + (bigendian ? 1 : 0)] = CLIP8(ss_int % 256);
|
||||||
|
imOut->image8[yy][xx * 2 + (bigendian ? 0 : 1)] = CLIP8(ss_int >> 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImagingSectionLeave(&cookie);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ImagingResampleHorizontal_32bpc(
|
ImagingResampleHorizontal_32bpc(
|
||||||
Imaging imOut, Imaging imIn, int offset, int ksize, int *bounds, double *kk
|
Imaging imOut, Imaging imIn, int offset, int ksize, int *bounds, double *kk
|
||||||
|
@ -574,7 +651,12 @@ ImagingResample(Imaging imIn, int xsize, int ysize, int filter, float box[4]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imIn->type == IMAGING_TYPE_SPECIAL) {
|
if (imIn->type == IMAGING_TYPE_SPECIAL) {
|
||||||
|
if (strncmp(imIn->mode, "I;16", 4) == 0) {
|
||||||
|
ResampleHorizontal = ImagingResampleHorizontal_16bpc;
|
||||||
|
ResampleVertical = ImagingResampleVertical_16bpc;
|
||||||
|
} else {
|
||||||
return (Imaging)ImagingError_ModeError();
|
return (Imaging)ImagingError_ModeError();
|
||||||
|
}
|
||||||
} else if (imIn->image8) {
|
} else if (imIn->image8) {
|
||||||
ResampleHorizontal = ImagingResampleHorizontal_8bpc;
|
ResampleHorizontal = ImagingResampleHorizontal_8bpc;
|
||||||
ResampleVertical = ImagingResampleVertical_8bpc;
|
ResampleVertical = ImagingResampleVertical_8bpc;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user