internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: python-pillow/Pillow

Issue:
Changing Jupyter plain text output on every cell run
### What did you do?

I'm using Pillow to generate simple images in Jupyter environment:

```python
from PIL import Image
Image.frombuffer('RGB', (16,16), bytes([100]*(16*16)))
```

It works nicely!

![image](https://user-images.githubusercontent.com/510678/146259055-bff41a14-b40d-452e-a354-11c05ce78b58.png)

### What did you expect to happen?

I expect every run of the cell produce the same output in the notebook file, to avoid needless changes in Git.

### What actually happened?

Every run produces different hash in text representation of the output. For example: `at 0x1075D8370`.

```diff
$ git diff test.ipynb 
diff --git a/test.ipynb b/test.ipynb
index f769d4b..a4dd8af 100644
--- a/test.ipynb
+++ b/test.ipynb
@@ -9,7 +9,7 @@
      "data": {
       "image/png": "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAGUlEQVR4nGPc62fCQApgIkn1qIZRDUNKAwADRwFfBBwAnwAAAABJRU5ErkJggg==",
       "text/plain": [
-       "<PIL.Image.Image image mode=RGB size=16x16 at 0x1075D8370>"
+       "<PIL.Image.Image image mode=RGB size=16x16 at 0x108C50160>"
       ]
      },
      "execution_count": 1,
```

Compare with Matplotlib output:

```json
     "data": {
      "image/png": "...",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     }
```

### What are your OS, Python and Pillow versions?

* OS: Mac OS 10.15.6
* Python: 3.9.8
* Pillow: 8.4.0


Discussion:

Resolving patch:
diff --git a/src/PIL/Image.py b/src/PIL/Image.py
--- a/src/PIL/Image.py
+++ b/src/PIL/Image.py
@@ -644,6 +644,22 @@ def __repr__(self):
             id(self),
         )
 
+    def _repr_pretty_(self, p, cycle):
+        """IPython plain text display support"""
+
+        # Same as __repr__ but without unpredicatable id(self),
+        # to keep Jupyter notebook `text/plain` output stable.
+        p.text(
+            "<%s.%s image mode=%s size=%dx%d>"
+            % (
+                self.__class__.__module__,
+                self.__class__.__name__,
+                self.mode,
+                self.size[0],
+                self.size[1],
+            )
+        )
+
     def _repr_png_(self):
         """iPython display hook support
 


Test patch:
diff --git a/Tests/test_image.py b/Tests/test_image.py
--- a/Tests/test_image.py
+++ b/Tests/test_image.py
@@ -88,6 +88,17 @@ def test_sanity(self):
         # with pytest.raises(MemoryError):
         #   Image.new("L", (1000000, 1000000))
 
+    def test_repr_pretty(self):
+        class Pretty:
+            def text(self, text):
+                self.pretty_output = text
+
+        im = Image.new("L", (100, 100))
+
+        p = Pretty()
+        im._repr_pretty_(p, None)
+        assert p.pretty_output == "<PIL.Image.Image image mode=L size=100x100>"
+
     def test_open_formats(self):
         PNGFILE = "Tests/images/hopper.png"
         JPGFILE = "Tests/images/hopper.jpg"
Repository: python-pillow/Pillow

Issue:
size 0,0 image use `.save()`/`.tobytes()` throw `SystemError: tile cannot extend outside image`
### What did you do?
Create a size (0,0) image instead of None, for convenient in coding,
```python
x.width
x.height
# other stuffs
x.tobytes()
```
to get rid of
```python
if x:
    x.width
    x.height
   # other stuffs
    x.tobytes()
```

### What did you expect to happen?
Normal, probably return `b''`

### What actually happened?
```python
---------------------------------------------------------------------------
SystemError                               Traceback (most recent call last)
<ipython-input-0-d240cdef7328> in <module>
----> 1 Image.new("RGB",(0,0)).tobytes()

c:\program files\python38\lib\site-packages\PIL\Image.py in tobytes(self, encoder_name, *args)
    720         # unpack data
    721         e = _getencoder(self.mode, encoder_name, args)
--> 722         e.setimage(self.im)
    723
    724         bufsize = max(65536, self.size[0] * 4)  # see RawEncode.c

SystemError: tile cannot extend outside image
```
### What are your OS, Python and Pillow versions?

* OS: Win10 1803
* Python: 3.8.10
* Pillow: 9.0.0

```python
from PIL import Image
Image.new("RGB",(0,0)).tobytes()
```



Discussion:
`.save` throw the same error as well.
Just to be clear, what format are trying to save the image as?
the `.save` is `.jpg`
When I try and save a (0, 0) JPEG, if I push past the Pillow error, I get "Empty JPEG image (DNL not supported)" which is coming from libjpeg itself - https://github.com/freedesktop/libjpeg/blob/b4f886fcbb692e20fb4da4e6e3ead57f79444734/jcmaster.c#L54-L57. So it doesn't look like it is possible to create a (0, 0) JPEG file.

I've created PR #5938 to fix the error coming from `tobytes()`.

Resolving patch:
diff --git a/src/PIL/Image.py b/src/PIL/Image.py
--- a/src/PIL/Image.py
+++ b/src/PIL/Image.py
@@ -716,6 +716,9 @@ def tobytes(self, encoder_name="raw", *args):
 
         self.load()
 
+        if self.width == 0 or self.height == 0:
+            return b""
+
         # unpack data
         e = _getencoder(self.mode, encoder_name, args)
         e.setimage(self.im)


Test patch:
diff --git a/Tests/test_image.py b/Tests/test_image.py
--- a/Tests/test_image.py
+++ b/Tests/test_image.py
@@ -786,6 +786,11 @@ def test_exif_load_from_fp(self):
                 34665: 196,
             }
 
+    @pytest.mark.parametrize("size", ((1, 0), (0, 1), (0, 0)))
+    def test_zero_tobytes(self, size):
+        im = Image.new("RGB", size)
+        assert im.tobytes() == b""
+
     def test_categories_deprecation(self):
         with pytest.warns(DeprecationWarning):
             assert hopper().category == 0
Repository: python-pillow/Pillow

Issue:
Spider file with last line black
### What did you do?

I ran the code below and then open the image in Fiji (ImageJ)

### What did you expect to happen?

Create an image with a gradient that goes from 0 to 1 diagonally

### What actually happened?

Created the image correctly but the last row of pixels is 0 (black). I don't know if this is a problem of Pillow in saving to spi or of imagej in opening spi.

### What versions of Pillow and Python are you using?

4.1.1

```python
from __future__ import division
from PIL import Image
import numpy as np

def gradient(i,j,S):
    return 1/2*(i+j)/(S-1)

# Create Image
S=512
Mpix=np.fromfunction(gradient,(S,S),dtype=np.float32,S=S)
Img=Image.fromarray(Mpix,mode="F")

# Save Image
Img.save("TestPIL_32.spi","spider")
```



Discussion:
I've taken a look at this, and I can confirm that it does show up in the Fiji interface with a black line. It's part of the image data, since it also shows up in the histogram. 

I've also looked at the spider image in a hexeditor, and it's not there. So either Fiji is wrong, or there's an off by one somewhere in the image size such that it's reading one beyond the end of the image and filling that with 0s instead of actual data. 

Resolving patch:
diff --git a/src/PIL/SpiderImagePlugin.py b/src/PIL/SpiderImagePlugin.py
--- a/src/PIL/SpiderImagePlugin.py
+++ b/src/PIL/SpiderImagePlugin.py
@@ -238,17 +238,18 @@ def makeSpiderHeader(im):
     if 1024 % lenbyt != 0:
         labrec += 1
     labbyt = labrec * lenbyt
-    hdr = []
     nvalues = int(labbyt / 4)
+    if nvalues < 23:
+        return []
+
+    hdr = []
     for i in range(nvalues):
         hdr.append(0.0)
 
-    if len(hdr) < 23:
-        return []
-
     # NB these are Fortran indices
     hdr[1] = 1.0  # nslice (=1 for an image)
     hdr[2] = float(nrow)  # number of rows per slice
+    hdr[3] = float(nrow)  # number of records in the image
     hdr[5] = 1.0  # iform for 2D image
     hdr[12] = float(nsam)  # number of pixels per line
     hdr[13] = float(labrec)  # number of records in file header
@@ -259,10 +260,7 @@ def makeSpiderHeader(im):
     hdr = hdr[1:]
     hdr.append(0.0)
     # pack binary data into a string
-    hdrstr = []
-    for v in hdr:
-        hdrstr.append(struct.pack("f", v))
-    return hdrstr
+    return [struct.pack("f", v) for v in hdr]
 
 
 def _save(im, fp, filename):


Test patch:
Repository: python-pillow/Pillow

Issue:
PIL.ImageFont.truetype takes size in points, but not convert to size in pixels, before FT_Set_Pixel_Sizes is called
In result, drawn text is smaller than should be.

Call hierarchy:
```
(FontImage.py)
truetype 
FreeTypeFont.__init__
core.getfont
(_imagingft.c)
getfont
FT_Set_Pixel_Sizes
```


Discussion:

Resolving patch:
diff --git a/src/PIL/ImageFont.py b/src/PIL/ImageFont.py
--- a/src/PIL/ImageFont.py
+++ b/src/PIL/ImageFont.py
@@ -839,7 +839,7 @@ def truetype(font=None, size=10, index=0, encoding="", layout_engine=None):
                  :file:`/System/Library/Fonts/` and :file:`~/Library/Fonts/` on
                  macOS.
 
-    :param size: The requested size, in points.
+    :param size: The requested size, in pixels.
     :param index: Which font face to load (default is first available face).
     :param encoding: Which font encoding to use (default is Unicode). Possible
                      encodings include (see the FreeType documentation for more


Test patch:
Repository: python-pillow/Pillow

Issue:
Cannot modify the first frame of a MPO with asymmetric sized frames after seek
### What did you do?
Did a seek(1) to the second frame followed by a seek(0) back to the first, and a transpose

### What did you expect to happen?

The transpose

### What actually happened?

Segmentation fault: 11

### What are your OS, Python and Pillow versions?

* OS: OSX 10.15.7 and Ubuntu 20.04
* Python: 3.8.11 and 3.10.2
* Pillow: 9.0.1

This is an edge case issue with images created by the Nikon coolpix 500b (and possibly others), which appears to embed a couple "thumbnails" in the image files. Pillow (reasonably) detects this as a 3-frame MPO. For some reason, however, seeking back to the first frame and trying to modify it after seeking to any other frame crashes with a seg fault.

For the example below I used this image (not sure on the licensing, just the first I googled):
https://img.photographyblog.com/reviews/nikon_coolpix_b500/photos/nikon_coolpix_b500_02.jpg

```python
from PIL import Image
im = Image.open('nikon_coolpix_b500_02.jpg')
im.seek(1)
im.seek(0)
im.transpose(Image.FLIP_LEFT_RIGHT) # => Segment fault: 11
```

If it helps, I noticed that the `im.size` doesn't update after the `seek(0)` back to the first frame, even though `tell` reports the correct frame:
```python
im = Image.open('nikon_coolpix_b500_02.jpg')
im.size #  =>  (4608, 3456)
im.seek(1)
im.size #  =>  (640, 480)
im.seek(0)
im.size #  =>  (640, 480)
im.tell() # => 0
```
For my particular case, the problematic usage was some legacy code trying to detect animations that is better handled by checking `n_frames`, so I was able to work around it. Mainly documenting the issue in case anyone else runs into it.


Discussion:

Resolving patch:
diff --git a/src/PIL/MpoImagePlugin.py b/src/PIL/MpoImagePlugin.py
--- a/src/PIL/MpoImagePlugin.py
+++ b/src/PIL/MpoImagePlugin.py
@@ -46,6 +46,7 @@ def _open(self):
         self._after_jpeg_open()
 
     def _after_jpeg_open(self, mpheader=None):
+        self._initial_size = self.size
         self.mpinfo = mpheader if mpheader is not None else self._getmp()
         self.n_frames = self.mpinfo[0xB001]
         self.__mpoffsets = [
@@ -77,6 +78,7 @@ def seek(self, frame):
         segment = self.fp.read(2)
         if not segment:
             raise ValueError("No data found for frame")
+        self._size = self._initial_size
         if i16(segment) == 0xFFE1:  # APP1
             n = i16(self.fp.read(2)) - 2
             self.info["exif"] = ImageFile._safe_read(self.fp, n)


Test patch:
diff --git a/Tests/test_file_mpo.py b/Tests/test_file_mpo.py
--- a/Tests/test_file_mpo.py
+++ b/Tests/test_file_mpo.py
@@ -85,6 +85,9 @@ def test_frame_size():
         im.seek(1)
         assert im.size == (680, 480)
 
+        im.seek(0)
+        assert im.size == (640, 480)
+
 
 def test_ignore_frame_size():
     # Ignore the different size of the second frame
Repository: python-pillow/Pillow

Issue:
Updated harfbuzz to 4.0.0



Discussion:

Resolving patch:
diff --git a/winbuild/build_prepare.py b/winbuild/build_prepare.py
--- a/winbuild/build_prepare.py
+++ b/winbuild/build_prepare.py
@@ -280,9 +280,9 @@ def cmd_msbuild(
         "libs": [r"imagequant.lib"],
     },
     "harfbuzz": {
-        "url": "https://github.com/harfbuzz/harfbuzz/archive/3.4.0.zip",
-        "filename": "harfbuzz-3.4.0.zip",
-        "dir": "harfbuzz-3.4.0",
+        "url": "https://github.com/harfbuzz/harfbuzz/archive/4.0.0.zip",
+        "filename": "harfbuzz-4.0.0.zip",
+        "dir": "harfbuzz-4.0.0",
         "build": [
             cmd_cmake("-DHB_HAVE_FREETYPE:BOOL=TRUE"),
             cmd_nmake(target="clean"),


Test patch:
Repository: python-pillow/Pillow

Issue:
ImageStat module incompatibility with color channels having range > 256
Recently a user names **Cecilia** asked a [question](https://stackoverflow.com/questions/56843624/why-is-imagestat-returning-incorrect-statistics-for-signed-integer-images-mode) on StackOverflow stating:-

> Why is ImageStat returning incorrect statistics for signed integer images (`mode='I'`)?

I was the one who answered the question, and added a little **PS** in the end, for the OP to follow. But it seems like OP didn't. Anyways.

The question asked, 'why doesn't `ImageStat`of **PIL** give the same results as the `Imagestat` from `Numpy` or `Matlab` (Matplotlib)'. My answer is quite self explanatory, on what I observed in the module.

Let me reiterate what i stated there:-

> Upon doing Source Code Analysis of ImageStat module, i came to know that the module is specifically built to deal with images having 0 ≤ sample space > 256, or images having pixel values in the range (0 ≤ value ≤ 255).

Module `ImageStat` is incompatible, if the single channel value of a pixel exceeds 255 (Like in case of Signed integer color mode). But there doesn't exists any mention of this in the PIL documentation. So, I would request you add this info in the description of `ImageStat` module in the upcoming PIL documentations.

Secondly, the module is error prone, i.e. it doesn't check the mode of the image before doing any processing over it, so if the image mode is a `RGB` or `L` (greyscale) it works fine, but if the image mode is `I` it works, but produces undesirable results (more to this in my answer on StackOverflow). So, I would request to add some detection mechanism inside the module too, so that if a user still tries to pass in a incompatible image, they receive a error message stating the reason (rather then throwing incorrect results, and confusing the user).

 


Discussion:

Resolving patch:
diff --git a/src/PIL/Image.py b/src/PIL/Image.py
--- a/src/PIL/Image.py
+++ b/src/PIL/Image.py
@@ -1492,11 +1492,12 @@ def getprojection(self):
 
     def histogram(self, mask=None, extrema=None):
         """
-        Returns a histogram for the image. The histogram is returned as
-        a list of pixel counts, one for each pixel value in the source
-        image. If the image has more than one band, the histograms for
-        all bands are concatenated (for example, the histogram for an
-        "RGB" image contains 768 values).
+        Returns a histogram for the image. The histogram is returned as a
+        list of pixel counts, one for each pixel value in the source
+        image. Counts are grouped into 256 bins for each band, even if
+        the image has more than 8 bits per band. If the image has more
+        than one band, the histograms for all bands are concatenated (for
+        example, the histogram for an "RGB" image contains 768 values).
 
         A bilevel image (mode "1") is treated as a greyscale ("L") image
         by this method.


Test patch:
Repository: python-pillow/Pillow

Issue:
ImageShow.show() for DisplayViewer doesn't work if no title is given
To reproduce the bug, just run ".show()" on any image object, while only having imagemagick's `display` viewer on the PATH.

```python
from PIL import Image
Image.new('RGB', (10, 10)).show()
```
```
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.10/site-packages/PIL/Image.py", line 2259, in show
    _show(self, title=title)
  File "/usr/lib/python3.10/site-packages/PIL/Image.py", line 3233, in _show
    ImageShow.show(image, **options)
  File "/usr/lib/python3.10/site-packages/PIL/ImageShow.py", line 55, in show
    if viewer.show(image, title=title, **options):
  File "/usr/lib/python3.10/site-packages/PIL/ImageShow.py", line 79, in show
    return self.show_image(image, **options)
  File "/usr/lib/python3.10/site-packages/PIL/ImageShow.py", line 105, in show_image
    return self.show_file(self.save_image(image), **options)
  File "/usr/lib/python3.10/site-packages/PIL/ImageShow.py", line 212, in show_file
    subprocess.Popen(args)
  File "/usr/lib/python3.10/subprocess.py", line 966, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/lib/python3.10/subprocess.py", line 1775, in _execute_child
    self.pid = _posixsubprocess.fork_exec(
TypeError: expected str, bytes or os.PathLike object, not NoneType
```

The reason is that the DisplayViewer class just appends `options["title"]` to the argument list: https://github.com/python-pillow/Pillow/blob/15dc2914692c9c19270b4fd55fa6226a94b17647/src/PIL/ImageShow.py#L274
But the default value for title is None: https://github.com/python-pillow/Pillow/blob/15dc2914692c9c19270b4fd55fa6226a94b17647/src/PIL/ImageShow.py#L51


Discussion:

Resolving patch:
diff --git a/src/PIL/ImageShow.py b/src/PIL/ImageShow.py
--- a/src/PIL/ImageShow.py
+++ b/src/PIL/ImageShow.py
@@ -270,8 +270,9 @@ def show_file(self, path=None, **options):
             else:
                 raise TypeError("Missing required argument: 'path'")
         args = ["display"]
-        if "title" in options:
-            args += ["-title", options["title"]]
+        title = options.get("title")
+        if title:
+            args += ["-title", title]
         args.append(path)
 
         subprocess.Popen(args)
@@ -368,8 +369,9 @@ def show_file(self, path=None, **options):
             else:
                 raise TypeError("Missing required argument: 'path'")
         args = ["xv"]
-        if "title" in options:
-            args += ["-name", options["title"]]
+        title = options.get("title")
+        if title:
+            args += ["-name", title]
         args.append(path)
 
         subprocess.Popen(args)


Test patch:
Repository: python-pillow/Pillow

Issue:
Black-and-white PDF export regression in Pillow 8.3.x
Black-and-white image export to PDF seems to blanket fail starting in PIL/Pillow 8.3.x. The version was reported to me by a user--I have not verified the switchover point.

Below is code which causes PDF generation to succeed (print a rectangle) in greyscale, but fails for black-and-white.

```python
#!/usr/bin/env python3
import PIL, PIL.Image, PIL.ImageDraw

# Works in 8.2.0, fails in 8.3.0
IMAGE_MODE="1"
WHITE=1
BLACK=0

# Works in 8.2.0 and 8.3.0
#IMAGE_MODE="L"
#WHITE=255
#BLACK=0

page = PIL.Image.new(mode=IMAGE_MODE, size=(200, 200), color=WHITE)
page_draw = PIL.ImageDraw.Draw(page)
page_draw.rectangle(((0,0), (99, 99)), outline=BLACK, fill=WHITE, width=1) # Rectangle for debugging print cutoff, and to look nice.

with open("test.pdf", "wb") as f:
    page.save(f, format="pdf")
```

Reproduced using two different Linux versions in Python 3.x, and multiple Pillow versions.
This bug report was verified with Python 3.10.2 and Pillow 9.0.1

Originally reported as: https://github.com/za3k/qr-backup/issues/24


Discussion:
[fail.pdf](https://github.com/python-pillow/Pillow/files/8319721/fail.pdf)
[success.pdf](https://github.com/python-pillow/Pillow/files/8319722/success.pdf)

Both files display fine on Chrome web preview, but on almost every other PDF viewer tried, one looks like random garbage.
While macOS Preview also displays the PDF correctly, I can see that Firefox does not.

Testing, I found this is due to #5430
From the original reporter: Moon Reader on Android; Firefox, Libreoffice Draw, and Evince on Linux

From me: xpdf on Linux

Aside: Looks like a great feature! I love tiny PDFs

Resolving patch:
diff --git a/src/PIL/PdfImagePlugin.py b/src/PIL/PdfImagePlugin.py
--- a/src/PIL/PdfImagePlugin.py
+++ b/src/PIL/PdfImagePlugin.py
@@ -127,7 +127,6 @@ def _save(im, fp, filename, save_all=False):
                 filter = "DCTDecode"
                 colorspace = PdfParser.PdfName("DeviceGray")
                 procset = "ImageB"  # grayscale
-                bits = 1
             elif im.mode == "L":
                 filter = "DCTDecode"
                 # params = f"<< /Predictor 15 /Columns {width-2} >>"


Test patch:
Repository: python-pillow/Pillow

Issue:
'float' object cannot be interpreted as an integer exception when applying point transforms
### What did you do?
Following the docs to apply point transforms:
https://pillow.readthedocs.io/en/stable/handbook/tutorial.html?highlight=.point(#applying-point-transforms

### What actually happened?
The following exception was raised: `'float' object cannot be interpreted as an integer`.

### What are your OS, Python and Pillow versions?

* OS: Windows 11 Pro (22000.556)
* Python: 3.10.4 (packaged by conda-forge)
* Pillow: 9.1.0

Code to reproduce
```python
from PIL import Image

image = Image.open(image_path).convert('RGBA')
alpha_channel = image.getchannel('A')
image.putalpha(alpha_channel.point(lambda x: x * 0.5))
```

With Pillow 8.3.2 and Python 3.8, the above code worked well.

Edit: I've tested Pillow 9.1.0 with Python 3.9.12 and it works fine, so it seems to be an issue related to Python 3.10.x


Discussion:
Thanks. This would be because of https://docs.python.org/3/c-api/long.html#c.PyLong_AsLong
> Changed in version 3.10: This function will no longer use `__int__()`.

I've created PR #6188 to resolve this.

Resolving patch:
diff --git a/src/PIL/Image.py b/src/PIL/Image.py
--- a/src/PIL/Image.py
+++ b/src/PIL/Image.py
@@ -1720,6 +1720,8 @@ def point(self, data):
             # FIXME: _imaging returns a confusing error message for this case
             raise ValueError("point operation not supported for this mode")
 
+        if mode != "F":
+            lut = [round(i) for i in lut]
         return self._new(self.im.point(lut, mode))
 
     def putalpha(self, alpha):


Test patch:
diff --git a/Tests/test_image_point.py b/Tests/test_image_point.py
--- a/Tests/test_image_point.py
+++ b/Tests/test_image_point.py
@@ -10,6 +10,7 @@ def test_sanity():
         im.point(list(range(256)))
     im.point(list(range(256)) * 3)
     im.point(lambda x: x)
+    im.point(lambda x: x * 1.2)
 
     im = im.convert("I")
     with pytest.raises(ValueError):