Repository: python-pillow/Pillow

Issue:
Image.show() problem with I;16 mode TIFFs
<!--
Thank you for reporting an issue.

Follow these guidelines to ensure your issue is handled properly.

If you have a ...

1.  General question: consider asking the question on Stack Overflow
    with the python-imaging-library tag:

    * https://stackoverflow.com/questions/tagged/python-imaging-library

    Do not ask a question in both places.

    If you think you have found a bug or have an unexplained exception
    then file a bug report here.

2.  Bug report: include a self-contained, copy-pastable example that
    generates the issue if possible. Be concise with code posted.
    Guidelines on how to provide a good bug report:

    * https://stackoverflow.com/help/mcve

    Bug reports which follow these guidelines are easier to diagnose,
    and are often handled much more quickly.

3.  Feature request: do a quick search of existing issues
    to make sure this has not been asked before.

We know asking good questions takes effort, and we appreciate your time.
Thank you.
-->

### What did you do?

Loaded a 16 bit integer TIFF file and showed it.

### What did you expect to happen?

That the image looks exactly the same as when opened manually.

### What actually happened?

It looked very different. 

I can't share the original image I am working with, but it becomes almost completely white, whereas it was mostly black before. 

I generated another example (code below). I can't upload it here, because GitHub doesn't accept .tif. 

The black one on the left side is the actual correct one opened manually.

![Screenshot ](https://user-images.githubusercontent.com/62176388/85736642-f2d1b700-b6fe-11ea-9528-e196d0e89138.png)

 The problem might be the temporary conversion to BMP. (Uneducated guess)

### What are your OS, Python and Pillow versions?

* OS: Windows 10 and WSL Ubuntu 18.04
* Python: 3.8.2
* Pillow: 7.1.2

<!--
Please include **code** that reproduces the issue and whenever possible, an **image** that demonstrates the issue. Please upload images to GitHub, not to third-party file hosting sites. If necessary, add the image to a zip or tar archive.

The best reproductions are self-contained scripts with minimal dependencies. If you are using a framework such as Plone, Django, or Buildout, try to replicate the issue just using Pillow.
-->

```python
from PIL import Image 

# code used to generate the example image
# img = Image.new('I;16', (1000,1000), 70)

# code that causes issue
with Image.open('test_generated.tif') as img:
    print(img.mode) # I;16
    print(img.format) # TIFF 
    img.show()
```

EDIT:
[test_generated.zip](https://github.com/python-pillow/Pillow/files/4836715/test_generated.zip)



Discussion:
If you compress your original image into a zip or tgz, then you should be able to upload it.
I'm pretty sure it's because the default conversions are using the 0-255 range of the i;16 and clipping the rest to 255. 
> If you compress your original image into a zip or tgz, then you should be able to upload it.

I'm not allowed to share it. The generated example is enough to reproduce and analyze the error, isn't it?
I uploaded it as a .zip.

> I'm pretty sure it's because the default conversions are using the 0-255 range of the i;16 and clipping the rest to 255.

When generating the example picture (code above) I used higher number than 255 for the intensitiy (instead of now 70). They all produced blank white images. Makes sense regarding your explanation.
I was just reading your message that you couldn't upload a .tif, and trying to offer a solution.

Regarding your problem, it's something of a known issue. See #3159, and the related #3011
Note that #4080 was merged and released in 7.1.0, meaning that `show` should now always convert the image to PNG, not BMP. However, due to the following line, images are always converted to a different mode unless they are in one of 1, RGBA, or LA modes: https://github.com/python-pillow/Pillow/blob/4f6145655b6fa35ec8dd3600041418087e399758/src/PIL/ImageShow.py#L62
This is likely no longer necessary, since PNG supports I;16 mode, as well as most (if not all) others.

Resolving patch:
diff --git a/src/PIL/ImageShow.py b/src/PIL/ImageShow.py
--- a/src/PIL/ImageShow.py
+++ b/src/PIL/ImageShow.py
@@ -71,7 +71,8 @@ def show(self, image, **options):
 
         # save temporary image to disk
         if not (
-            image.mode in ("1", "RGBA") or (self.format == "PNG" and image.mode == "LA")
+            image.mode in ("1", "RGBA")
+            or (self.format == "PNG" and image.mode in ("I;16", "LA"))
         ):
             base = Image.getmodebase(image.mode)
             if image.mode != base:


Test patch: