diff --git a/src/PIL/TiffImagePlugin.py b/src/PIL/TiffImagePlugin.py index ff5a6f9e91b..198bd422ef1 100644 --- a/src/PIL/TiffImagePlugin.py +++ b/src/PIL/TiffImagePlugin.py @@ -685,22 +685,33 @@ def _setitem(self, tag: int, value: Any, legacy_api: bool) -> None: else: self.tagtype[tag] = TiffTags.UNDEFINED if all(isinstance(v, IFDRational) for v in values): - self.tagtype[tag] = ( - TiffTags.RATIONAL - if all(v >= 0 for v in values) - else TiffTags.SIGNED_RATIONAL - ) + for v in values: + assert isinstance(v, IFDRational) + if v < 0: + self.tagtype[tag] = TiffTags.SIGNED_RATIONAL + break + else: + self.tagtype[tag] = TiffTags.RATIONAL elif all(isinstance(v, int) for v in values): - if all(0 <= v < 2**16 for v in values): + short = True + signed_short = True + long = True + for v in values: + assert isinstance(v, int) + if short and not (0 <= v < 2**16): + short = False + if signed_short and not (-(2**15) < v < 2**15): + signed_short = False + if long and v < 0: + long = False + if short: self.tagtype[tag] = TiffTags.SHORT - elif all(-(2**15) < v < 2**15 for v in values): + elif signed_short: self.tagtype[tag] = TiffTags.SIGNED_SHORT + elif long: + self.tagtype[tag] = TiffTags.LONG else: - self.tagtype[tag] = ( - TiffTags.LONG - if all(v >= 0 for v in values) - else TiffTags.SIGNED_LONG - ) + self.tagtype[tag] = TiffTags.SIGNED_LONG elif all(isinstance(v, float) for v in values): self.tagtype[tag] = TiffTags.DOUBLE elif all(isinstance(v, str) for v in values): @@ -718,7 +729,10 @@ def _setitem(self, tag: int, value: Any, legacy_api: bool) -> None: is_ifd = self.tagtype[tag] == TiffTags.LONG and isinstance(values, dict) if not is_ifd: - values = tuple(info.cvt_enum(value) for value in values) + values = tuple( + info.cvt_enum(value) if isinstance(value, str) else value + for value in values + ) dest = self._tags_v1 if legacy_api else self._tags_v2