From 304cf484aaba5285cfdf854c31cfe51505de3f9a Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Thu, 27 Jun 2024 13:29:22 +1000 Subject: [PATCH] Do not presume "xmp" info simply because "XML:com.adobe.xmp" info exists --- Tests/test_imageops.py | 10 ++++++++++ src/PIL/ImageOps.py | 23 ++++++++++++----------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/Tests/test_imageops.py b/Tests/test_imageops.py index 27a6090c5fa..64ef929c48d 100644 --- a/Tests/test_imageops.py +++ b/Tests/test_imageops.py @@ -432,6 +432,16 @@ def check(orientation_im: Image.Image) -> None: assert 0x0112 not in transposed_im.getexif() +def test_exif_transpose_xml_without_xmp() -> None: + with Image.open("Tests/images/xmp_tags_orientation.png") as im: + assert im.getexif()[0x0112] == 3 + assert "XML:com.adobe.xmp" in im.info + + del im.info["xmp"] + transposed_im = ImageOps.exif_transpose(im) + assert 0x0112 not in transposed_im.getexif() + + def test_exif_transpose_in_place() -> None: with Image.open("Tests/images/orientation_rectangle.jpg") as im: assert im.size == (2, 1) diff --git a/src/PIL/ImageOps.py b/src/PIL/ImageOps.py index 6d2814345a3..a84c0834561 100644 --- a/src/PIL/ImageOps.py +++ b/src/PIL/ImageOps.py @@ -709,17 +709,18 @@ def exif_transpose(image: Image.Image, *, in_place: bool = False) -> Image.Image exif_image.info["exif"] = exif.tobytes() elif "Raw profile type exif" in exif_image.info: exif_image.info["Raw profile type exif"] = exif.tobytes().hex() - elif "XML:com.adobe.xmp" in exif_image.info: - for pattern in ( - r'tiff:Orientation="([0-9])"', - r"([0-9])", - ): - exif_image.info["XML:com.adobe.xmp"] = re.sub( - pattern, "", exif_image.info["XML:com.adobe.xmp"] - ) - exif_image.info["xmp"] = re.sub( - pattern.encode(), b"", exif_image.info["xmp"] - ) + for key in ("XML:com.adobe.xmp", "xmp"): + if key in exif_image.info: + for pattern in ( + r'tiff:Orientation="([0-9])"', + r"([0-9])", + ): + value = exif_image.info[key] + exif_image.info[key] = ( + re.sub(pattern, "", value) + if isinstance(value, str) + else re.sub(pattern.encode(), b"", value) + ) if not in_place: return transposed_image elif not in_place: