mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 09:57:43 +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