Skip to content

Commit

Permalink
Patch exif rotation bug
Browse files Browse the repository at this point in the history
The bug: python-pillow#4238
See the bug for 2 PRs that fix the problem.
  • Loading branch information
Mapiarz committed Jan 28, 2020
1 parent 6e0f07b commit 5869247
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 7 deletions.
35 changes: 30 additions & 5 deletions src/PIL/TiffImagePlugin.py
Expand Up @@ -279,6 +279,20 @@ def _limit_rational(val, max_val):
return n_d[::-1] if inv else n_d


def _limit_signed_rational(val, max_val, min_val):
frac = Fraction(val)
n_d = frac.numerator, frac.denominator

if min(n_d) < min_val:
n_d = _limit_rational(val, abs(min_val))

if max(n_d) > max_val:
val = Fraction(*n_d)
n_d = _limit_rational(val, max_val)

return n_d


def _libtiff_version():
return Image.core.libtiff_version.split("\n")[0].split("Version ")[1]

Expand Down Expand Up @@ -553,12 +567,22 @@ def _setitem(self, tag, value, legacy_api):
else:
self.tagtype[tag] = TiffTags.UNDEFINED
if all(isinstance(v, IFDRational) for v in values):
self.tagtype[tag] = TiffTags.RATIONAL
self.tagtype[tag] = (
TiffTags.RATIONAL
if all(v >= 0 for v in values)
else TiffTags.SIGNED_RATIONAL
)
elif all(isinstance(v, int) for v in values):
if all(v < 2 ** 16 for v in values):
if all(0 <= v < 2 ** 16 for v in values):
self.tagtype[tag] = TiffTags.SHORT
elif all(-(2 ** 15) < v < 2 ** 15 for v in values):
self.tagtype[tag] = TiffTags.SIGNED_SHORT
else:
self.tagtype[tag] = TiffTags.LONG
self.tagtype[tag] = (
TiffTags.LONG
if all(v >= 0 for v in values)
else TiffTags.SIGNED_LONG
)
elif all(isinstance(v, float) for v in values):
self.tagtype[tag] = TiffTags.DOUBLE
else:
Expand Down Expand Up @@ -705,7 +729,7 @@ def combine(a, b):
@_register_writer(5)
def write_rational(self, *values):
return b"".join(
self._pack("2L", *_limit_rational(frac, 2 ** 31)) for frac in values
self._pack("2L", *_limit_rational(frac, 2 ** 32 - 1)) for frac in values
)

@_register_loader(7, 1)
Expand All @@ -728,7 +752,8 @@ def combine(a, b):
@_register_writer(10)
def write_signed_rational(self, *values):
return b"".join(
self._pack("2L", *_limit_rational(frac, 2 ** 30)) for frac in values
self._pack("2l", *_limit_signed_rational(frac, 2 ** 31 - 1, -(2 ** 31)))
for frac in values
)

def _ensure_read(self, fp, size):
Expand Down
4 changes: 2 additions & 2 deletions src/PIL/TiffTags.py
Expand Up @@ -120,7 +120,7 @@ def lookup(tag):
277: ("SamplesPerPixel", SHORT, 1),
278: ("RowsPerStrip", LONG, 1),
279: ("StripByteCounts", LONG, 0),
280: ("MinSampleValue", LONG, 0),
280: ("MinSampleValue", SHORT, 0),
281: ("MaxSampleValue", SHORT, 0),
282: ("XResolution", RATIONAL, 1),
283: ("YResolution", RATIONAL, 1),
Expand Down Expand Up @@ -182,7 +182,7 @@ def lookup(tag):
# FIXME add more tags here
34665: ("ExifIFD", LONG, 1),
34675: ("ICCProfile", UNDEFINED, 1),
34853: ("GPSInfoIFD", BYTE, 1),
34853: ("GPSInfoIFD", LONG, 1),
# MPInfo
45056: ("MPFVersion", UNDEFINED, 1),
45057: ("NumberOfImages", LONG, 1),
Expand Down

0 comments on commit 5869247

Please sign in to comment.