Deep-Software-Analytics/SweSetupBench-lite huggingface dataset:
Repository: python-pillow/Pillow

Problem statement:
PNG palette quantized save functionality different between 8.1.0 and 8.3.1
### What did you do?
Create a palette, quantize an image using this palette and save it.

### What did you expect to happen?
The palette information is stored correctly. I.e. the list of RGB values is the same in the saved image.
E.g. [0, 0, 0, 209, 254, 76, 217, 3, 3, 10, 66, 192,...]

### What actually happened?
The list of RGB values is corrupted.
E.g. [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3,...]

### What are your OS, Python and Pillow versions?

* OS: Tested on Windows and Azure Databricks (Ubuntu)
* Python: 3.6 & 3.8
* Pillow: 8.3.1 has the issue

```python
from PIL import Image
from itertools import cycle
import numpy as np

palette = [0, 0, 0, 209, 254, 76, 217, 3, 3, 10, 66, 192]
# palette must contain 768 values (256 * 3)
# repeat the colours until we get there
color_iter = cycle(palette)
expanded_palette_format = []
while True:
    expanded_palette_format.append(next(color_iter))
    if len(expanded_palette_format) == 768:
        break

assert len(expanded_palette_format) == 768
palette_image = Image.new('P', (16, 16))
palette_image.putpalette(expanded_palette_format)

# a new image that we want to apply the palette to
im_to_palette = np.array(
    [
        [[0, 0, 0,],[209, 254, 76], [217, 3, 3], [10, 66, 192]],
        [[0, 0, 0,],[209, 254, 76], [217, 3, 3], [10, 66, 192]],
        [[0, 0, 0,],[209, 254, 76], [217, 3, 3], [10, 66, 192]],
        [[0, 0, 0,],[209, 254, 76], [217, 3, 3], [10, 66, 192]]
    ],
    np.uint8
    )
im = Image.fromarray(im_to_palette).quantize(palette=palette_image, dither=0)

im.save(r"test.png")
saved_im = Image.open(r"test.png")

assert im.getpalette() == saved_im.getpalette()
# AssertionError
```

Please note that if I specifically pass the 'GIF' argument on save, it has the expected behaviour.
```python
im.save(r"test.png", "GIF")
saved_im = Image.open(r"test.png")

assert im.getpalette() == saved_im.getpalette()
```


Hints:

Patch:
diff --git a/src/PIL/Image.py b/src/PIL/Image.py
--- a/src/PIL/Image.py
+++ b/src/PIL/Image.py
@@ -1130,7 +1130,9 @@ def quantize(self, colors=256, method=None, kmeans=0, palette=None, dither=1):
                     "only RGB or L mode images can be quantized to a palette"
                 )
             im = self.im.convert("P", dither, palette.im)
-            return self._new(im)
+            new_im = self._new(im)
+            new_im.palette = palette.palette.copy()
+            return new_im
 
         im = self._new(self.im.quantize(colors, method, kmeans))
 


Test patch:
diff --git a/Tests/test_image_quantize.py b/Tests/test_image_quantize.py
--- a/Tests/test_image_quantize.py
+++ b/Tests/test_image_quantize.py
@@ -63,6 +63,7 @@ def test_quantize_no_dither():
 
     converted = image.quantize(dither=0, palette=palette)
     assert_image(converted, "P", converted.size)
+    assert converted.palette.palette == palette.palette.palette
 
 
 def test_quantize_dither_diff():
Repository: python-pillow/Pillow

Problem statement:
Problem rotating P images
```python
from PIL import Image
import random

img = Image.open('test.png')
rate = random.randint(30, 330)
img = img.rotate(rate)
img.show()
img.save('test_rotate.png')
```
![test](https://user-images.githubusercontent.com/37957822/127455530-f7437db9-b2df-4b89-be5b-5582b67b4eb8.png)
![test_rotate](https://user-images.githubusercontent.com/37957822/127455537-05a6a378-4ba9-4018-a22f-5f2dabbe6eea.png)


Hints:
The image generated by rotating the picture is a binary image
If you're looking for an immediate solution, you can convert it to RGB after opening.

```python
from PIL import Image
import random

img = Image.open('test.png').convert('RGB')
rate = random.randint(30, 330)
img = img.rotate(rate)
img.show()
img.save('test_rotate.png')
```
Thank you for your answer. It's useful
This problem was introduced by #5552

Patch:
diff --git a/src/PIL/Image.py b/src/PIL/Image.py
--- a/src/PIL/Image.py
+++ b/src/PIL/Image.py
@@ -2479,6 +2479,8 @@ def getdata(self):
             raise ValueError("missing method data")
 
         im = new(self.mode, size, fillcolor)
+        if self.mode == "P" and self.palette:
+            im.palette = self.palette.copy()
         im.info = self.info.copy()
         if method == MESH:
             # list of quads


Test patch:
diff --git a/Tests/test_image_transform.py b/Tests/test_image_transform.py
--- a/Tests/test_image_transform.py
+++ b/Tests/test_image_transform.py
@@ -32,6 +32,11 @@ def test_info(self):
             new_im = im.transform((100, 100), transform)
         assert new_im.info["comment"] == comment
 
+    def test_palette(self):
+        with Image.open("Tests/images/hopper.gif") as im:
+            transformed = im.transform(im.size, Image.AFFINE, [1, 0, 0, 0, 1, 0])
+            assert im.palette.palette == transformed.palette.palette
+
     def test_extent(self):
         im = hopper("RGB")
         (w, h) = im.size
Repository: python-pillow/Pillow

Problem statement:
Pillow 8.3 and NumPy
Throws exception with Pillow 8.3: `TypeError: __array__() takes 1 positional argument but 2 were given`

````python
with PIL.Image.open(filepath) as img:
    numpy.array( img, dtype=numpy.float32 )
````


Hints:
What version of Python are you using? What version of numpy?
Same problem here.
Python 3.7.4
numpy 1.21.0

workaround:
```python
with PIL.Image.open(filepath) as img:
    numpy.array(img).astype(np.float32)
```
Works with just about anything. The problem is that pillow newly implemented `__array__`, but only without arguments. Numpy requires `__array__` to take an optional dtype argument. This is used e.g. by numpy.array when the user passes a dtype argument. This should be with just about any numpy/python version.
fails with python 3.8 + 3.9, numpy 1.20 + 1.21
I'll send a patch.
We are seeing errors in `3.{6,7,8,9}`
Same issue in https://github.com/hyperspy/hyperspy/runs/2961516889 for all python version >=3.6 using the `imageio` library:

```python
                # Apply palette
>               frame_paletted = np.array(im, np.uint8)
E               TypeError: __array__() takes 1 positional argument but 2 were given

/opt/hostedtoolcache/Python/3.9.5/x64/lib/python3.9/site-packages/imageio/plugins/pillow.py:745: TypeError
```

The python 3.6 build is with numpy 1.17.1

Patch:
diff --git a/src/PIL/Image.py b/src/PIL/Image.py
--- a/src/PIL/Image.py
+++ b/src/PIL/Image.py
@@ -681,7 +681,7 @@ def _repr_png_(self):
             raise ValueError("Could not save to PNG for display") from e
         return b.getvalue()
 
-    def __array__(self):
+    def __array__(self, dtype=None):
         # numpy array interface support
         import numpy as np
 
@@ -700,7 +700,7 @@ def __array__(self):
         class ArrayData:
             __array_interface__ = new
 
-        return np.array(ArrayData())
+        return np.array(ArrayData(), dtype)
 
     def __getstate__(self):
         return [self.info, self.mode, self.size, self.getpalette(), self.tobytes()]


Test patch:
diff --git a/Tests/test_image_array.py b/Tests/test_image_array.py
--- a/Tests/test_image_array.py
+++ b/Tests/test_image_array.py
@@ -14,6 +14,10 @@ def test(mode):
         ai = numpy.array(im.convert(mode))
         return ai.shape, ai.dtype.str, ai.nbytes
 
+    def test_with_dtype(dtype):
+        ai = numpy.array(im, dtype=dtype)
+        assert ai.dtype == dtype
+
     # assert test("1") == ((100, 128), '|b1', 1600))
     assert test("L") == ((100, 128), "|u1", 12800)
 
@@ -27,6 +31,9 @@ def test(mode):
     assert test("RGBA") == ((100, 128, 4), "|u1", 51200)
     assert test("RGBX") == ((100, 128, 4), "|u1", 51200)
 
+    test_with_dtype(numpy.float64)
+    test_with_dtype(numpy.uint8)
+
     with Image.open("Tests/images/truncated_jpeg.jpg") as im_truncated:
         with pytest.raises(OSError):
             numpy.array(im_truncated)
Repository: python-pillow/Pillow

Problem statement:
CalledProcessError saving icns file to io.BytesIO()
Currently, writing an icns file to an io.ByteIO object fails. This operation is supported by other filetypes (jpg, png, ico, etc) so I'm not clear if this report falls under feature request or bug

### What did you do?
Write icns file to io.BytesIO() object
```python
from PIL import Image
import io
import base64

im = Image.new(mode="RGBA", size=(256,256), color=(0,100,246,255))
f = io.BytesIO()
im.save(fp=f, format="icns")

b64 = base64.b64encode(f.getvalue()).decode()
print(f'Image: {b64}')
```

### What did you expect to happen?
Fill the io.BytesIO object 

### What actually happened?
macOS's iconutil failed because it was provided an empty filename for output (-o)
```bash
subprocess.CalledProcessError: Command '['iconutil', '-c', 'icns', '-o', '', '/var/folders/91/q75bkgks1196cr1rsr0399540000gn/T/tmppmsm3z2y.iconset']' returned non-zero exit status 1.
```

I believe one solution would be if `filename` variable is empty then use a dummy name and after popen returns, read the file from disk.

### What are your OS, Python and Pillow versions?

* OS: macOS Mojave 10.14.6
* Python: 3.7.7
* Pillow: 7.1.2


Hints:
This would be fixed by merging #4526.

Patch:
diff --git a/src/PIL/IcnsImagePlugin.py b/src/PIL/IcnsImagePlugin.py
--- a/src/PIL/IcnsImagePlugin.py
+++ b/src/PIL/IcnsImagePlugin.py
@@ -337,6 +337,10 @@ def _save(im, fp, filename):
 
         # iconutil -c icns -o {} {}
 
+        fp_only = not filename
+        if fp_only:
+            f, filename = tempfile.mkstemp(".icns")
+            os.close(f)
         convert_cmd = ["iconutil", "-c", "icns", "-o", filename, iconset]
         convert_proc = subprocess.Popen(
             convert_cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL
@@ -349,6 +353,10 @@ def _save(im, fp, filename):
         if retcode:
             raise subprocess.CalledProcessError(retcode, convert_cmd)
 
+        if fp_only:
+            with open(filename, "rb") as f:
+                fp.write(f.read())
+
 
 Image.register_open(IcnsImageFile.format, IcnsImageFile, lambda x: x[:4] == b"icns")
 Image.register_extension(IcnsImageFile.format, ".icns")


Test patch:
diff --git a/Tests/test_file_icns.py b/Tests/test_file_icns.py
--- a/Tests/test_file_icns.py
+++ b/Tests/test_file_icns.py
@@ -55,6 +55,19 @@ def test_save_append_images(tmp_path):
             assert_image_equal(reread, provided_im)
 
 
+@pytest.mark.skipif(sys.platform != "darwin", reason="Requires macOS")
+def test_save_fp():
+    fp = io.BytesIO()
+
+    with Image.open(TEST_FILE) as im:
+        im.save(fp, format="ICNS")
+
+    with Image.open(fp) as reread:
+        assert reread.mode == "RGBA"
+        assert reread.size == (1024, 1024)
+        assert reread.format == "ICNS"
+
+
 def test_sizes():
     # Check that we can load all of the sizes, and that the final pixel
     # dimensions are as expected
Repository: python-pillow/Pillow

Problem statement:
On Windows, opening a TIFF with a pathlib.Path argument fails
### What did you do?

1. Create a tiff file (e.g. `from pylab import *; savefig("test.tiff")` using matplotlib).
2. Try to load it with Pillow, passing the path as pathlib.Path: `from PIL import Image; from pathlib import Path; Image.open(Path("test.tiff")).tobytes()`

### What did you expect to happen?

The image is correctly loaded (the same as `Image.open("test.tiff").tobytes()`; using a pathlib.Path also works just fine on Linux).

### What actually happened?

```
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "...\Miniconda3\lib\site-packages\PIL\Image.py", line 746, in tobytes
    self.load()
  File "...\Miniconda3\lib\site-packages\PIL\TiffImagePlugin.py", line 1078, in load
    return super(TiffImageFile, self).load()
  File "...\Miniconda3\lib\site-packages\PIL\ImageFile.py", line 177, in load
    self.map = Image.core.map(self.filename)
TypeError: argument 1 must be str, not WindowsPath
```

### What are your OS, Python and Pillow versions?

* OS: Windows 10
* Python: 3.7
* Pillow: 6.0.0


Hints:
I wasn't able to replicate this on AppVeyor. I don't suppose you could say if you're only experiencing this on Windows 10, and not Windows 7?

Also, while you would think this should be easy to reproduce in the right environment, could you provide a script from start to end, attaching a file if necessary, without matplotlib?
```python
from pathlib import Path
from PIL import Image

Image.new("RGBA", (100, 100)).save("test.tiff")
Image.open(Path("test.tiff")).tobytes()
```
reproes the bug for me.

I don't have readily access to a win7 machine with python.

This Pillow install is from PyPI, fwiw.
Thanks. I've created PR #3825 to resolve this.

Patch:
diff --git a/src/PIL/Image.py b/src/PIL/Image.py
--- a/src/PIL/Image.py
+++ b/src/PIL/Image.py
@@ -2643,10 +2643,10 @@ def open(fp, mode="r"):
 
     exclusive_fp = False
     filename = ""
-    if isPath(fp):
-        filename = fp
-    elif HAS_PATHLIB and isinstance(fp, Path):
+    if HAS_PATHLIB and isinstance(fp, Path):
         filename = str(fp.resolve())
+    elif isPath(fp):
+        filename = fp
 
     if filename:
         fp = builtins.open(filename, "rb")


Test patch:
diff --git a/Tests/test_image.py b/Tests/test_image.py
--- a/Tests/test_image.py
+++ b/Tests/test_image.py
@@ -76,6 +76,10 @@ def test_bad_mode(self):
     @unittest.skipUnless(Image.HAS_PATHLIB, "requires pathlib/pathlib2")
     def test_pathlib(self):
         from PIL.Image import Path
+        im = Image.open(Path("Tests/images/multipage-mmap.tiff"))
+        self.assertEqual(im.mode, "P")
+        self.assertEqual(im.size, (10, 10))
+
         im = Image.open(Path("Tests/images/hopper.jpg"))
         self.assertEqual(im.mode, "RGB")
         self.assertEqual(im.size, (128, 128))
Repository: python-pillow/Pillow

Problem statement:
Transforms and enhancements across all frames
It would be nice if transforms and enhancements could be applied on animations.


Hints:
What sort of transforms and enhancements?
for example.
https://pillow.readthedocs.io/en/stable/handbook/tutorial.html#geometrical-transforms

https://pillow.readthedocs.io/en/stable/handbook/tutorial.html#image-enhancement
So when you say that you'd like them to be applied on animations, what you mean is that you'd like to be able to apply them across all frames of an image at once?
yes. It seems to me that a lot of application would want a functionality like that.
Okay. What about a generic way to apply a method to all frames of an image?

So, for example -

```python
from PIL import Image, ImageSequence
im = Image.open('Tests/images/g4-multi.tiff')
ims = ImageSequence.all_frames(im, lambda im_frame: im_frame.rotate(180))
ims[0].save('out.tiff', save_all=True, append_images=ims[1:])
```

I've created this in PR #3778
lol, i was expecting a solution to this in....~5-10 years XD
@radarhere is that good 😄 

Patch:
diff --git a/src/PIL/ImageSequence.py b/src/PIL/ImageSequence.py
--- a/src/PIL/ImageSequence.py
+++ b/src/PIL/ImageSequence.py
@@ -54,3 +54,25 @@ def __next__(self):
 
     def next(self):
         return self.__next__()
+
+
+def all_frames(im, func=None):
+    """
+    Applies a given function to all frames in an image or a list of images.
+    The frames are returned as a list of separate images.
+
+    :param im: An image, or a list of images.
+    :param func: The function to apply to all of the image frames.
+    :returns: A list of images.
+    """
+    if not isinstance(im, list):
+        im = [im]
+
+    ims = []
+    for imSequence in im:
+        current = imSequence.tell()
+
+        ims += [im_frame.copy() for im_frame in Iterator(imSequence)]
+
+        imSequence.seek(current)
+    return [func(im) for im in ims] if func else ims


Test patch:
diff --git a/Tests/test_imagesequence.py b/Tests/test_imagesequence.py
--- a/Tests/test_imagesequence.py
+++ b/Tests/test_imagesequence.py
@@ -74,3 +74,25 @@ def test_palette_mmap(self):
         im.seek(0)
         color2 = im.getpalette()[0:3]
         self.assertEqual(color1, color2)
+
+    def test_all_frames(self):
+        # Test a single image
+        im = Image.open("Tests/images/iss634.gif")
+        ims = ImageSequence.all_frames(im)
+
+        self.assertEqual(len(ims), 42)
+        for i, im_frame in enumerate(ims):
+            self.assertFalse(im_frame is im)
+
+            im.seek(i)
+            self.assert_image_equal(im, im_frame)
+
+        # Test a series of images
+        ims = ImageSequence.all_frames([im, hopper(), im])
+        self.assertEqual(len(ims), 85)
+
+        # Test an operation
+        ims = ImageSequence.all_frames(im, lambda im_frame: im_frame.rotate(90))
+        for i, im_frame in enumerate(ims):
+            im.seek(i)
+            self.assert_image_equal(im.rotate(90), im_frame)
Repository: python-pillow/Pillow

Problem statement:
Save compressed TIFF only accepts float values for dpi
There is a trap in setting the resolution for compressed TIFF images.  

```python
# pillow v3.1.1

import PIL.Image
im = PIL.Image.new('CMYK', (100, 100))

dpi = 100.0  # works
dpi = 100  # fails

im.save('test.tif', format='TIFF',
        dpi=(dpi, dpi),
        compression='tiff_lzw',
        #compression='tiff_deflate',
        #compression='tiff_adobe_deflate'
        )
```

Integers fail silently resulting in the resolution value missing from the saved file. Floats work as expected.



Hints:

Patch:
diff --git a/src/PIL/TiffImagePlugin.py b/src/PIL/TiffImagePlugin.py
--- a/src/PIL/TiffImagePlugin.py
+++ b/src/PIL/TiffImagePlugin.py
@@ -567,6 +567,9 @@ def _setitem(self, tag, value, legacy_api):
         if self.tagtype[tag] == 7 and py3:
             values = [value.encode("ascii", 'replace') if isinstance(
                       value, str) else value]
+        elif self.tagtype[tag] == 5:
+            values = [float(v) if isinstance(v, int) else v
+                      for v in values]
 
         values = tuple(info.cvt_enum(value) for value in values)
 


Test patch:
diff --git a/Tests/test_file_libtiff.py b/Tests/test_file_libtiff.py
--- a/Tests/test_file_libtiff.py
+++ b/Tests/test_file_libtiff.py
@@ -231,6 +231,16 @@ def test_additional_metadata(self):
 
         TiffImagePlugin.WRITE_LIBTIFF = False
 
+    def test_int_dpi(self):
+        # issue #1765
+        im = hopper('RGB')
+        out = self.tempfile('temp.tif')
+        TiffImagePlugin.WRITE_LIBTIFF = True
+        im.save(out, dpi=(72, 72))
+        TiffImagePlugin.WRITE_LIBTIFF = False
+        reloaded = Image.open(out)
+        self.assertEqual(reloaded.info['dpi'], (72.0, 72.0))
+
     def test_g3_compression(self):
         i = Image.open('Tests/images/hopper_g4_500.tif')
         out = self.tempfile("temp.tif")
Repository: python-pillow/Pillow

Problem statement:
Gif duration setting is ignored
### What versions of Pillow and Python are you using?
Python 3.6.4
Pillow 5.0

Any animated gif I have tried the following lines of code on show no affect on the gif frame duration:

```python
> from PIL import Image
> f = Image.open('in.gif')
> f.save('out.gif', save_all=True, duration=400)
```


Hints:
Hi. To help with your immediate problem, try this -

```python
from PIL import Image
f = Image.open('in.gif')
f.info['duration'] = 400
f.save('out.gif', save_all=True)
```

What I'm guessing is happening is that the images you are opening already have a `duration` key, and this key is overwriting the `duration` argument you are passing in on save.

Patch:
diff --git a/src/PIL/GifImagePlugin.py b/src/PIL/GifImagePlugin.py
--- a/src/PIL/GifImagePlugin.py
+++ b/src/PIL/GifImagePlugin.py
@@ -457,7 +457,8 @@ def _save_all(im, fp, filename):
 
 
 def _save(im, fp, filename, save_all=False):
-    im.encoderinfo.update(im.info)
+    for k, v in im.info.items():
+        im.encoderinfo.setdefault(k, v)
     # header
     try:
         palette = im.encoderinfo["palette"]


Test patch:
diff --git a/Tests/test_file_gif.py b/Tests/test_file_gif.py
--- a/Tests/test_file_gif.py
+++ b/Tests/test_file_gif.py
@@ -305,9 +305,12 @@ def test_duration(self):
 
         out = self.tempfile('temp.gif')
         im = Image.new('L', (100, 100), '#000')
+
+        # Check that the argument has priority over the info settings
+        im.info['duration'] = 100
         im.save(out, duration=duration)
-        reread = Image.open(out)
 
+        reread = Image.open(out)
         self.assertEqual(reread.info['duration'], duration)
 
     def test_multiple_duration(self):
Repository: python-pillow/Pillow

Problem statement:
cryptic error message when saving to a file without a valid extension
### What did you do?
I tried to save a file with an invalid extension, e. g. ".5"

### What did you expect to happen?
I would expect getting an error message telling me that pillow doesn't know this extension.

### What actually happened?
I got a somewhat cryptic error message:

      File "/usr/local/lib/python3.5/dist-packages/PIL/Image.py", line 1683, in save
        format = EXTENSION[ext]
    KeyError: '.5'`

### What versions of Pillow and Python are you using?
Python 3.5.2 with pillow 3.4.2

```
from PIL import Image
im = Image.open('test.jpg')
im.save('2.5') # error
```

I think this could be easily fixed by adding a `try`/`except` block around line 1718 in Image.py (line number corresponds to the version on github) that re-raises the exception with a clear error message.




Hints:

Patch:
diff --git a/PIL/Image.py b/PIL/Image.py
--- a/PIL/Image.py
+++ b/PIL/Image.py
@@ -1715,7 +1715,10 @@ def save(self, fp, format=None, **params):
         if not format:
             if ext not in EXTENSION:
                 init()
-            format = EXTENSION[ext]
+            try:
+                format = EXTENSION[ext]
+            except KeyError:
+                raise ValueError('unknown file extension: {}'.format(ext))
 
         if format.upper() not in SAVE:
             init()


Test patch:
diff --git a/Tests/test_image.py b/Tests/test_image.py
--- a/Tests/test_image.py
+++ b/Tests/test_image.py
@@ -87,6 +87,11 @@ def test_tempfile(self):
             reloaded = Image.open(fp)
             self.assert_image_similar(im, reloaded, 20)
 
+    def test_unknown_extension(self):
+        im = hopper()
+        temp_file = self.tempfile("temp.unknown")
+        self.assertRaises(ValueError, lambda: im.save(temp_file))
+
     def test_internals(self):
 
         im = Image.new("L", (100, 100))