From 3ac9396e8c991e7baab66187af2a35c3f4e83605 Mon Sep 17 00:00:00 2001 From: wiredfool Date: Tue, 29 Dec 2015 22:00:36 +0000 Subject: [PATCH] Write round trip for rationals, including nan value --- PIL/TiffImagePlugin.py | 8 +++++--- PIL/TiffTags.py | 2 +- Tests/test_file_tiff_metadata.py | 14 ++++++++++++++ Tests/test_tiff_ifdrational.py | 17 ++++++++++++++++- 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/PIL/TiffImagePlugin.py b/PIL/TiffImagePlugin.py index 05a2d75d4..521c7c726 100644 --- a/PIL/TiffImagePlugin.py +++ b/PIL/TiffImagePlugin.py @@ -497,11 +497,13 @@ class ImageFileDirectory_v2(collections.MutableMapping): values = [value] if isinstance(value, basetypes) else value if tag not in self.tagtype: - try: + if info.type: self.tagtype[tag] = info.type - except KeyError: + else: self.tagtype[tag] = 7 - if all(isinstance(v, int) for v in values): + if all(isinstance(v, IFDRational) for v in values): + self.tagtype[tag] = 5 + elif all(isinstance(v, int) for v in values): if all(v < 2 ** 16 for v in values): self.tagtype[tag] = 3 else: diff --git a/PIL/TiffTags.py b/PIL/TiffTags.py index d8e304d87..d00164502 100644 --- a/PIL/TiffTags.py +++ b/PIL/TiffTags.py @@ -23,7 +23,7 @@ from collections import namedtuple class TagInfo(namedtuple("_TagInfo", "value name type length enum")): __slots__ = [] - def __new__(cls, value=None, name="unknown", type=4, length=0, enum=None): + def __new__(cls, value=None, name="unknown", type=None, length=0, enum=None): return super(TagInfo, cls).__new__( cls, value, name, type, length, enum or {}) diff --git a/Tests/test_file_tiff_metadata.py b/Tests/test_file_tiff_metadata.py index 9290d1d2b..1b88fca99 100644 --- a/Tests/test_file_tiff_metadata.py +++ b/Tests/test_file_tiff_metadata.py @@ -185,6 +185,20 @@ class TestFileTiffMetadata(PillowTestCase): self.assertEqual(im.tag_v2.tagtype[34675], 1) self.assertTrue(im.info['icc_profile']) + def test_exif_div_zero(self): + im = hopper() + info = TiffImagePlugin.ImageFileDirectory_v2() + info[41988] = TiffImagePlugin.IFDRational(0,0) + + out = self.tempfile('temp.tiff') + im.save(out, tiffinfo=info, compression='raw') + + reloaded = Image.open(out) + self.assertEqual(0, reloaded.tag_v2[41988][0].numerator) + self.assertEqual(0, reloaded.tag_v2[41988][0].denominator) + + + if __name__ == '__main__': unittest.main() diff --git a/Tests/test_tiff_ifdrational.py b/Tests/test_tiff_ifdrational.py index 05f66d5c4..5654d4c9c 100644 --- a/Tests/test_tiff_ifdrational.py +++ b/Tests/test_tiff_ifdrational.py @@ -1,7 +1,8 @@ from __future__ import print_function -from helper import PillowTestCase +from helper import PillowTestCase, hopper +from PIL import TiffImagePlugin, Image from PIL.TiffImagePlugin import IFDRational from fractions import Fraction @@ -44,3 +45,17 @@ class Test_IFDRational(PillowTestCase): self.assert_(xres and 1) self.assert_(xres and yres) + + def test_ifd_rational_save(self): + for libtiff in (True, False): + TiffImagePlugin.WRITE_LIBTIFF = libtiff + + im = hopper() + out = self.tempfile('temp.tiff') + res = IFDRational(301,1) + im.save(out, dpi=(res,res), compression='raw') + + reloaded = Image.open(out) + self.assertEqual(float(IFDRational(301,1)), + float(reloaded.tag_v2[282])) +