diff --git a/Tests/test_file_tga.py b/Tests/test_file_tga.py index 226b899dc..77695f2d1 100644 --- a/Tests/test_file_tga.py +++ b/Tests/test_file_tga.py @@ -53,10 +53,10 @@ class TestFileTga(PillowTestCase): # Generate a new test name every time so the # test will not fail with permission error # on Windows. - test_file = self.tempfile("temp.tga") + out = self.tempfile("temp.tga") - original_im.save(test_file, rle=rle) - saved_im = Image.open(test_file) + original_im.save(out, rle=rle) + saved_im = Image.open(out) if rle: self.assertEqual( saved_im.info["compression"], @@ -95,34 +95,93 @@ class TestFileTga(PillowTestCase): test_file = "Tests/images/tga_id_field.tga" im = Image.open(test_file) - test_file = self.tempfile("temp.tga") + out = self.tempfile("temp.tga") # Save - im.save(test_file) - test_im = Image.open(test_file) + im.save(out) + test_im = Image.open(out) self.assertEqual(test_im.size, (100, 100)) + self.assertEqual(test_im.info["id_section"], im.info["id_section"]) # RGBA save - im.convert("RGBA").save(test_file) - test_im = Image.open(test_file) + im.convert("RGBA").save(out) + test_im = Image.open(out) self.assertEqual(test_im.size, (100, 100)) + def test_save_id_section(self): + test_file = "Tests/images/rgb32rle.tga" + im = Image.open(test_file) + + out = self.tempfile("temp.tga") + + # Check there is no id section + im.save(out) + test_im = Image.open(out) + self.assertNotIn("id_section", test_im.info) + + # Save with custom id section + im.save(out, id_section=b"Test content") + test_im = Image.open(out) + self.assertEqual(test_im.info["id_section"], b"Test content") + + # Save with custom id section greater than 255 characters + id_section = b"Test content" * 25 + self.assert_warning(UserWarning, + lambda: im.save(out, id_section=id_section)) + test_im = Image.open(out) + self.assertEqual(test_im.info["id_section"], id_section[:255]) + + test_file = "Tests/images/tga_id_field.tga" + im = Image.open(test_file) + + # Save with no id section + im.save(out, id_section="") + test_im = Image.open(out) + self.assertNotIn("id_section", test_im.info) + + def test_save_orientation(self): + test_file = "Tests/images/rgb32rle.tga" + im = Image.open(test_file) + self.assertEqual(im.info["orientation"], -1) + + out = self.tempfile("temp.tga") + + im.save(out, orientation=1) + test_im = Image.open(out) + self.assertEqual(test_im.info["orientation"], 1) + def test_save_rle(self): test_file = "Tests/images/rgb32rle.tga" im = Image.open(test_file) + self.assertEqual(im.info["compression"], "tga_rle") - test_file = self.tempfile("temp.tga") + out = self.tempfile("temp.tga") # Save - im.save(test_file) - test_im = Image.open(test_file) + im.save(out) + test_im = Image.open(out) self.assertEqual(test_im.size, (199, 199)) + self.assertEqual(test_im.info["compression"], "tga_rle") + + # Save without compression + im.save(out, compression=None) + test_im = Image.open(out) + self.assertNotIn("compression", test_im.info) # RGBA save - im.convert("RGBA").save(test_file) - test_im = Image.open(test_file) + im.convert("RGBA").save(out) + test_im = Image.open(out) self.assertEqual(test_im.size, (199, 199)) + test_file = "Tests/images/tga_id_field.tga" + im = Image.open(test_file) + self.assertNotIn("compression", im.info) + + # Save with compression + im.save(out, compression="tga_rle") + test_im = Image.open(out) + self.assertEqual(test_im.info["compression"], "tga_rle") + def test_save_l_transparency(self): # There are 559 transparent pixels in la.tga. num_transparent = 559 @@ -133,10 +192,10 @@ class TestFileTga(PillowTestCase): self.assertEqual( im.getchannel("A").getcolors()[0][0], num_transparent) - test_file = self.tempfile("temp.tga") - im.save(test_file) + out = self.tempfile("temp.tga") + im.save(out) - test_im = Image.open(test_file) + test_im = Image.open(out) self.assertEqual(test_im.mode, "LA") self.assertEqual( test_im.getchannel("A").getcolors()[0][0], num_transparent) diff --git a/src/PIL/TgaImagePlugin.py b/src/PIL/TgaImagePlugin.py index 57b6ae2c8..02893e837 100644 --- a/src/PIL/TgaImagePlugin.py +++ b/src/PIL/TgaImagePlugin.py @@ -20,6 +20,8 @@ from . import Image, ImageFile, ImagePalette from ._binary import i8, i16le as i16, o8, o16le as o16 +import warnings + __version__ = "0.3" @@ -53,7 +55,7 @@ class TgaImageFile(ImageFile.ImageFile): # process header s = self.fp.read(18) - idlen = i8(s[0]) + id_len = i8(s[0]) colormaptype = i8(s[1]) imagetype = i8(s[2]) @@ -100,8 +102,8 @@ class TgaImageFile(ImageFile.ImageFile): if imagetype & 8: self.info["compression"] = "tga_rle" - if idlen: - self.info["id_section"] = self.fp.read(idlen) + if id_len: + self.info["id_section"] = self.fp.read(id_len) if colormaptype: # read palette @@ -151,11 +153,23 @@ def _save(im, fp, filename): except KeyError: raise IOError("cannot write mode %s as TGA" % im.mode) - rle = im.encoderinfo.get("rle", False) - + if "rle" in im.encoderinfo: + rle = im.encoderinfo["rle"] + else: + compression = im.encoderinfo.get("compression", + im.info.get("compression")) + rle = compression == "tga_rle" if rle: imagetype += 8 + id_section = im.encoderinfo.get("id_section", + im.info.get("id_section", "")) + id_len = len(id_section) + if id_len > 255: + id_len = 255 + id_section = id_section[:255] + warnings.warn("id_section has been trimmed to 255 characters") + if colormaptype: colormapfirst, colormaplength, colormapentry = 0, 256, 24 else: @@ -166,11 +180,12 @@ def _save(im, fp, filename): else: flags = 0 - orientation = im.info.get("orientation", -1) + orientation = im.encoderinfo.get("orientation", + im.info.get("orientation", -1)) if orientation > 0: flags = flags | 0x20 - fp.write(b"\000" + + fp.write(o8(id_len) + o8(colormaptype) + o8(imagetype) + o16(colormapfirst) + @@ -183,6 +198,9 @@ def _save(im, fp, filename): o8(bits) + o8(flags)) + if id_section: + fp.write(id_section) + if colormaptype: fp.write(im.im.getpalette("RGB", "BGR"))