Repository: python-pillow/Pillow

Issue:
PIL doesn't seem to handle the color map correctly in some color indexed TGA files
Please see my question in [Stack Overflow](https://stackoverflow.com/questions/63151906/is-there-any-other-attribute-that-affetcts-how-colors-are-displayed-on-an-indexe) where I explain everything in greater detail and more importantly, where Mark Setchell explains why he thinks there is a bug in PIL when handling some color indexed TGA files.

Basically, I am working with a sample color indexed TGA file to test a script that would invert its colors.

But before any of that, the issue is that PIL doesn't seem to handle the color map correctly when open it and the values of the color palette end up being wrong.

These are the sample files: [CCM8.TGA](https://www.fileformat.info/format/tga/sample/c36e10e31828483d832ef67561e20d5a/download) and [UCM8.TGA](https://www.fileformat.info/format/tga/sample/34402cd832c3456eb82628798f54709a/download).
And you will see that if you open show any of them:
```python
from PIL import Image
Image.open('CCM8.TGA').show()
```
PIL shows:
![pQ6IH](https://user-images.githubusercontent.com/1219020/89067243-ce54a480-d366-11ea-91f1-f7c95b843d27.png)
When it should be:
![IpPCy](https://user-images.githubusercontent.com/1219020/89067319-f512db00-d366-11ea-9af7-e7c813be8669.png)

As I said, I wrote all the details on that post. If you want me to submit more information here, please let me know.

I am using Pillow 7.0 on Fedora 32 and Python 3.8.


Discussion:
Do you have images that demonstrate this problem, that are able to be added to the test suite under the Pillow license?
I have recreated those images which you can add to the test suite.

[TGA_samples.zip](https://github.com/python-pillow/Pillow/files/5013124/TGA_samples.zip)

Thank you.
I've created #5396 to fix an unrelated bug mentioned in the StackOverflow answer.
I've created #5400 to fix the reading in of colors.
You would think that would be the end of it, but saving straightaway to PNG (`show()` uses the PNG format) is actually another problem again, and I think that won't be fixed until we significantly improve ImagePalette.

If #5400 is merged, then the following will work.
```python
from PIL import Image
Image.open('UCM8.TGA').convert("RGB").show()
```

Resolving patch:
diff --git a/src/PIL/Image.py b/src/PIL/Image.py
--- a/src/PIL/Image.py
+++ b/src/PIL/Image.py
@@ -830,7 +830,7 @@ def load(self):
                 arr = bytes(
                     value for (index, value) in enumerate(arr) if index % 4 != 3
                 )
-            self.im.putpalette(mode, arr)
+            palette_length = self.im.putpalette(mode, arr)
             self.palette.dirty = 0
             self.palette.rawmode = None
             if "transparency" in self.info:
@@ -841,6 +841,7 @@ def load(self):
                 self.palette.mode = "RGBA"
             else:
                 self.palette.mode = "RGB"
+                self.palette.palette = self.im.getpalette()[: palette_length * 3]
 
         if self.im:
             if cffi and USE_CFFI_ACCESS:


Test patch:
diff --git a/Tests/test_file_tga.py b/Tests/test_file_tga.py
--- a/Tests/test_file_tga.py
+++ b/Tests/test_file_tga.py
@@ -65,10 +65,15 @@ def roundtrip(original_im):
                         roundtrip(original_im)
 
 
-def test_palette_depth_16():
+def test_palette_depth_16(tmp_path):
     with Image.open("Tests/images/p_16.tga") as im:
         assert_image_equal_tofile(im.convert("RGB"), "Tests/images/p_16.png")
 
+        out = str(tmp_path / "temp.png")
+        im.save(out)
+        with Image.open(out) as reloaded:
+            assert_image_equal_tofile(reloaded.convert("RGB"), "Tests/images/p_16.png")
+
 
 def test_id_field():
     # tga file with id field