mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 01:47:47 +03:00 
			
		
		
		
	Merge pull request #8171 from radarhere/xmp
This commit is contained in:
		
						commit
						6a44854e5b
					
				| 
						 | 
					@ -8,6 +8,7 @@ import sys
 | 
				
			||||||
import tempfile
 | 
					import tempfile
 | 
				
			||||||
import warnings
 | 
					import warnings
 | 
				
			||||||
from pathlib import Path
 | 
					from pathlib import Path
 | 
				
			||||||
 | 
					from types import ModuleType
 | 
				
			||||||
from typing import IO, Any
 | 
					from typing import IO, Any
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import pytest
 | 
					import pytest
 | 
				
			||||||
| 
						 | 
					@ -35,6 +36,12 @@ from .helper import (
 | 
				
			||||||
    skip_unless_feature,
 | 
					    skip_unless_feature,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ElementTree: ModuleType | None
 | 
				
			||||||
 | 
					try:
 | 
				
			||||||
 | 
					    from defusedxml import ElementTree
 | 
				
			||||||
 | 
					except ImportError:
 | 
				
			||||||
 | 
					    ElementTree = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Deprecation helper
 | 
					# Deprecation helper
 | 
				
			||||||
def helper_image_new(mode: str, size: tuple[int, int]) -> Image.Image:
 | 
					def helper_image_new(mode: str, size: tuple[int, int]) -> Image.Image:
 | 
				
			||||||
| 
						 | 
					@ -921,6 +928,21 @@ class TestImage:
 | 
				
			||||||
        with Image.open("Tests/images/hopper.gif") as im:
 | 
					        with Image.open("Tests/images/hopper.gif") as im:
 | 
				
			||||||
            assert im.getxmp() == {}
 | 
					            assert im.getxmp() == {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_getxmp_padded(self) -> None:
 | 
				
			||||||
 | 
					        im = Image.new("RGB", (1, 1))
 | 
				
			||||||
 | 
					        im.info["xmp"] = (
 | 
				
			||||||
 | 
					            b'<?xpacket begin="\xef\xbb\xbf" id="W5M0MpCehiHzreSzNTczkc9d"?>\n'
 | 
				
			||||||
 | 
					            b'<x:xmpmeta xmlns:x="adobe:ns:meta/" />\n<?xpacket end="w"?>\x00\x00'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        if ElementTree is None:
 | 
				
			||||||
 | 
					            with pytest.warns(
 | 
				
			||||||
 | 
					                UserWarning,
 | 
				
			||||||
 | 
					                match="XMP data cannot be read without defusedxml dependency",
 | 
				
			||||||
 | 
					            ):
 | 
				
			||||||
 | 
					                assert im.getxmp() == {}
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            assert im.getxmp() == {"xmpmeta": None}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.mark.parametrize("size", ((1, 0), (0, 1), (0, 0)))
 | 
					    @pytest.mark.parametrize("size", ((1, 0), (0, 1), (0, 0)))
 | 
				
			||||||
    def test_zero_tobytes(self, size: tuple[int, int]) -> None:
 | 
					    def test_zero_tobytes(self, size: tuple[int, int]) -> None:
 | 
				
			||||||
        im = Image.new("RGB", size)
 | 
					        im = Image.new("RGB", size)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1511,7 +1511,7 @@ class Image:
 | 
				
			||||||
            return {}
 | 
					            return {}
 | 
				
			||||||
        if "xmp" not in self.info:
 | 
					        if "xmp" not in self.info:
 | 
				
			||||||
            return {}
 | 
					            return {}
 | 
				
			||||||
        root = ElementTree.fromstring(self.info["xmp"])
 | 
					        root = ElementTree.fromstring(self.info["xmp"].rstrip(b"\x00"))
 | 
				
			||||||
        return {get_name(root.tag): get_value(root)}
 | 
					        return {get_name(root.tag): get_value(root)}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def getexif(self) -> Exif:
 | 
					    def getexif(self) -> Exif:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -96,7 +96,7 @@ def APP(self, marker):
 | 
				
			||||||
            self.info["exif"] = s
 | 
					            self.info["exif"] = s
 | 
				
			||||||
            self._exif_offset = self.fp.tell() - n + 6
 | 
					            self._exif_offset = self.fp.tell() - n + 6
 | 
				
			||||||
    elif marker == 0xFFE1 and s[:29] == b"http://ns.adobe.com/xap/1.0/\x00":
 | 
					    elif marker == 0xFFE1 and s[:29] == b"http://ns.adobe.com/xap/1.0/\x00":
 | 
				
			||||||
        self.info["xmp"] = s.split(b"\x00")[1]
 | 
					        self.info["xmp"] = s.split(b"\x00", 1)[1]
 | 
				
			||||||
    elif marker == 0xFFE2 and s[:5] == b"FPXR\0":
 | 
					    elif marker == 0xFFE2 and s[:5] == b"FPXR\0":
 | 
				
			||||||
        # extract FlashPix information (incomplete)
 | 
					        # extract FlashPix information (incomplete)
 | 
				
			||||||
        self.info["flashpix"] = s  # FIXME: value will change
 | 
					        self.info["flashpix"] = s  # FIXME: value will change
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user