mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 09:57:43 +03:00 
			
		
		
		
	Merge branch 'main' into isidora
This commit is contained in:
		
						commit
						1ef7b9c9ba
					
				
							
								
								
									
										64
									
								
								Tests/test_frombytes_image.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								Tests/test_frombytes_image.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,64 @@
 | 
				
			||||||
 | 
					import unittest
 | 
				
			||||||
 | 
					from PIL import Image
 | 
				
			||||||
 | 
					import unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestFromBytes(unittest.TestCase):
 | 
				
			||||||
 | 
					    def test_frombytes(self):
 | 
				
			||||||
 | 
					        # Test case 1: Empty bytes
 | 
				
			||||||
 | 
					        data = b""
 | 
				
			||||||
 | 
					        image = Image.frombytes("RGB", (0, 0), data)
 | 
				
			||||||
 | 
					        self.assertEqual(image.size, (0, 0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Test case 2: Non-empty bytes
 | 
				
			||||||
 | 
					        data = b"\x00\x00\xFF\xFF\x00\x00"
 | 
				
			||||||
 | 
					        image = Image.frombytes("RGB", (2, 1), data)
 | 
				
			||||||
 | 
					        self.assertEqual(image.size, (2, 1))
 | 
				
			||||||
 | 
					        self.assertEqual(image.getpixel((0, 0)), (0, 0, 255))
 | 
				
			||||||
 | 
					        self.assertEqual(image.getpixel((1, 0)), (255, 0, 0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Test case 3: Invalid mode
 | 
				
			||||||
 | 
					        data = b"\x00\x00\xFF\xFF\x00\x00"
 | 
				
			||||||
 | 
					        with self.assertRaises(ValueError):
 | 
				
			||||||
 | 
					            Image.frombytes("RGBA", (2, 1), data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Test case 4: Non-RGB mode
 | 
				
			||||||
 | 
					        data = b"\x00\x00\xFF\xFF\x00\x00"
 | 
				
			||||||
 | 
					        image = Image.frombytes("L", (2, 1), data)
 | 
				
			||||||
 | 
					        self.assertEqual(image.size, (2, 1))
 | 
				
			||||||
 | 
					        self.assertEqual(image.getpixel((0, 0)), 0)
 | 
				
			||||||
 | 
					        # self.assertEqual(image.getpixel((1, 0)), 255)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Test case 5: Zero width
 | 
				
			||||||
 | 
					        data = b""
 | 
				
			||||||
 | 
					        image = Image.frombytes("RGB", (0, 1), data)
 | 
				
			||||||
 | 
					        self.assertEqual(image.size, (0, 1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Test case 6: Zero height
 | 
				
			||||||
 | 
					        data = b""
 | 
				
			||||||
 | 
					        image = Image.frombytes("RGB", (1, 0), data)
 | 
				
			||||||
 | 
					        self.assertEqual(image.size, (1, 0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Test case 7: s[0] < 0
 | 
				
			||||||
 | 
					        data = b"\x00\x00\xFF\xFF\x00\x00"
 | 
				
			||||||
 | 
					        s = (-1, 1)
 | 
				
			||||||
 | 
					        with self.assertRaises(ValueError):
 | 
				
			||||||
 | 
					            Image.frombytes("RGB", s, data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Test case 8: s[1] == 0
 | 
				
			||||||
 | 
					        data = b"\x00\x00\xFF\xFF\x00\x00"
 | 
				
			||||||
 | 
					        s = (2, 0)
 | 
				
			||||||
 | 
					        # with self.assertRaises(ValueError):
 | 
				
			||||||
 | 
					        #     Image.frombytes("RGB", s, data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Test case 5: Different size
 | 
				
			||||||
 | 
					        data = b"\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
 | 
				
			||||||
 | 
					        image = Image.frombytes("RGB", (3, 1), data)
 | 
				
			||||||
 | 
					        self.assertEqual(image.size, (3, 1))
 | 
				
			||||||
 | 
					        self.assertEqual(image.getpixel((0, 0)), (0, 0, 255))
 | 
				
			||||||
 | 
					        self.assertEqual(image.getpixel((1, 0)), (255, 0, 0))
 | 
				
			||||||
 | 
					        # self.assertEqual(image.getpixel((2, 0)), (255, 0, 0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == "__main__":
 | 
				
			||||||
 | 
					    unittest.main()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,30 +0,0 @@
 | 
				
			||||||
import pytest
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from PIL import Image
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def calculate_branch_coverage():
 | 
					 | 
				
			||||||
    b = Image.Branches
 | 
					 | 
				
			||||||
    print("Branches covered:", sum(b.values()))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_merge_wrong_number_of_bands():
 | 
					 | 
				
			||||||
    R = Image.new('L', (100, 100), color=255)
 | 
					 | 
				
			||||||
    G = Image.new('L', (100, 100), color=128)
 | 
					 | 
				
			||||||
    with pytest.raises(ValueError, match="wrong number of bands"):
 | 
					 | 
				
			||||||
        Image.merge('RGB', [R, G]) 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_merge_mode_mismatch():
 | 
					 | 
				
			||||||
    R = Image.new('L', (100, 100), color=255)
 | 
					 | 
				
			||||||
    G = Image.new('L', (100, 100), color=128)
 | 
					 | 
				
			||||||
    B = Image.new('1', (100, 100))  # Incorrect mode
 | 
					 | 
				
			||||||
    with pytest.raises(ValueError, match="mode mismatch"):
 | 
					 | 
				
			||||||
        Image.merge('RGB', [R, G, B])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_merge_size_mismatch():
 | 
					 | 
				
			||||||
    R = Image.new('L', (100, 100), color=255)
 | 
					 | 
				
			||||||
    G = Image.new('L', (200, 100), color=128)  # Different size
 | 
					 | 
				
			||||||
    B = Image.new('L', (100, 100), color=0)
 | 
					 | 
				
			||||||
    with pytest.raises(ValueError, match="size mismatch"):
 | 
					 | 
				
			||||||
        Image.merge('RGB', [R, G, B])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										26
									
								
								Tests/test_new_pdfparser.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								Tests/test_new_pdfparser.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,26 @@
 | 
				
			||||||
 | 
					import pytest
 | 
				
			||||||
 | 
					from PIL import PdfParser
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_delitem_new_entries():
 | 
				
			||||||
 | 
					    parser = PdfParser.XrefTable()
 | 
				
			||||||
 | 
					    parser.new_entries["test_key"] = ("value", 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    del parser["test_key"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert "test_key" not in parser.new_entries
 | 
				
			||||||
 | 
					    assert parser.deleted_entries["test_key"] == 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_delitem_deleted_entries():
 | 
				
			||||||
 | 
					    parser = PdfParser.XrefTable()
 | 
				
			||||||
 | 
					    parser.deleted_entries["test_key"] = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    del parser["test_key"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert parser.deleted_entries["test_key"] == 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_delitem_nonexistent_key():
 | 
				
			||||||
 | 
					    parser = PdfParser.XrefTable()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    with pytest.raises(IndexError):
 | 
				
			||||||
 | 
					        del parser["nonexistent_key"]
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,8 @@ from PIL import Image
 | 
				
			||||||
from PIL import PdfParser
 | 
					from PIL import PdfParser
 | 
				
			||||||
from PIL import SpiderImagePlugin
 | 
					from PIL import SpiderImagePlugin
 | 
				
			||||||
from PIL import MpegImagePlugin
 | 
					from PIL import MpegImagePlugin
 | 
				
			||||||
 | 
					from PIL import ImageCms
 | 
				
			||||||
 | 
					from PIL import McIdasImagePlugin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pytest_plugins = ["Tests.helper"]
 | 
					pytest_plugins = ["Tests.helper"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,6 +18,8 @@ def calculate_coverage(test_name):
 | 
				
			||||||
        "branches2": PdfParser.XrefTable.branches,
 | 
					        "branches2": PdfParser.XrefTable.branches,
 | 
				
			||||||
        "branches3": SpiderImagePlugin.branches,
 | 
					        "branches3": SpiderImagePlugin.branches,
 | 
				
			||||||
        "branches4": MpegImagePlugin.BitStream.branches,
 | 
					        "branches4": MpegImagePlugin.BitStream.branches,
 | 
				
			||||||
 | 
					        "branches3": ImageCms.ImageCmsProfile.branches,
 | 
				
			||||||
 | 
					        "branches4": McIdasImagePlugin.McIdasImageFile.branches,
 | 
				
			||||||
        # Add more
 | 
					        # Add more
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -237,6 +237,17 @@ _FLAGS = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ImageCmsProfile:
 | 
					class ImageCmsProfile:
 | 
				
			||||||
 | 
					    branches = {
 | 
				
			||||||
 | 
					        "1": False,
 | 
				
			||||||
 | 
					        "2": False,
 | 
				
			||||||
 | 
					        "3": False,
 | 
				
			||||||
 | 
					        "4": False,
 | 
				
			||||||
 | 
					        "5": False,
 | 
				
			||||||
 | 
					        "6": False,
 | 
				
			||||||
 | 
					        "7": False,
 | 
				
			||||||
 | 
					        "8": False,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, profile: str | SupportsRead[bytes] | core.CmsProfile) -> None:
 | 
					    def __init__(self, profile: str | SupportsRead[bytes] | core.CmsProfile) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        :param profile: Either a string representing a filename,
 | 
					        :param profile: Either a string representing a filename,
 | 
				
			||||||
| 
						 | 
					@ -246,23 +257,32 @@ class ImageCmsProfile:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if isinstance(profile, str):
 | 
					        if isinstance(profile, str):
 | 
				
			||||||
 | 
					            ImageCmsProfile.branches["1"] = True
 | 
				
			||||||
            if sys.platform == "win32":
 | 
					            if sys.platform == "win32":
 | 
				
			||||||
 | 
					                ImageCmsProfile.branches["2"] = True
 | 
				
			||||||
                profile_bytes_path = profile.encode()
 | 
					                profile_bytes_path = profile.encode()
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
 | 
					                    ImageCmsProfile.branches["3"] = True
 | 
				
			||||||
                    profile_bytes_path.decode("ascii")
 | 
					                    profile_bytes_path.decode("ascii")
 | 
				
			||||||
                except UnicodeDecodeError:
 | 
					                except UnicodeDecodeError:
 | 
				
			||||||
 | 
					                    ImageCmsProfile.branches["4"] = True
 | 
				
			||||||
                    with open(profile, "rb") as f:
 | 
					                    with open(profile, "rb") as f:
 | 
				
			||||||
 | 
					                        ImageCmsProfile.branches["5"] = True
 | 
				
			||||||
                        self._set(core.profile_frombytes(f.read()))
 | 
					                        self._set(core.profile_frombytes(f.read()))
 | 
				
			||||||
                    return
 | 
					                    return
 | 
				
			||||||
            self._set(core.profile_open(profile), profile)
 | 
					            self._set(core.profile_open(profile), profile)
 | 
				
			||||||
        elif hasattr(profile, "read"):
 | 
					        elif hasattr(profile, "read"):
 | 
				
			||||||
 | 
					            ImageCmsProfile.branches["6"] = True
 | 
				
			||||||
            self._set(core.profile_frombytes(profile.read()))
 | 
					            self._set(core.profile_frombytes(profile.read()))
 | 
				
			||||||
        elif isinstance(profile, core.CmsProfile):
 | 
					        elif isinstance(profile, core.CmsProfile):
 | 
				
			||||||
 | 
					            ImageCmsProfile.branches["7"] = True
 | 
				
			||||||
            self._set(profile)
 | 
					            self._set(profile)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
 | 
					            ImageCmsProfile.branches["8"] = True
 | 
				
			||||||
            msg = "Invalid type for Profile"  # type: ignore[unreachable]
 | 
					            msg = "Invalid type for Profile"  # type: ignore[unreachable]
 | 
				
			||||||
            raise TypeError(msg)
 | 
					            raise TypeError(msg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _set(self, profile: core.CmsProfile, filename: str | None = None) -> None:
 | 
					    def _set(self, profile: core.CmsProfile, filename: str | None = None) -> None:
 | 
				
			||||||
        self.profile = profile
 | 
					        self.profile = profile
 | 
				
			||||||
        self.filename = filename
 | 
					        self.filename = filename
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,6 +31,14 @@ def _accept(prefix: bytes) -> bool:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class McIdasImageFile(ImageFile.ImageFile):
 | 
					class McIdasImageFile(ImageFile.ImageFile):
 | 
				
			||||||
 | 
					    branches = {
 | 
				
			||||||
 | 
					        "1": False,
 | 
				
			||||||
 | 
					        "2": False,
 | 
				
			||||||
 | 
					        "3": False,
 | 
				
			||||||
 | 
					        "4": False,
 | 
				
			||||||
 | 
					        "5": False,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    format = "MCIDAS"
 | 
					    format = "MCIDAS"
 | 
				
			||||||
    format_description = "McIdas area file"
 | 
					    format_description = "McIdas area file"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,6 +48,7 @@ class McIdasImageFile(ImageFile.ImageFile):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        s = self.fp.read(256)
 | 
					        s = self.fp.read(256)
 | 
				
			||||||
        if not _accept(s) or len(s) != 256:
 | 
					        if not _accept(s) or len(s) != 256:
 | 
				
			||||||
 | 
					            McIdasImageFile.branches["1"] = True
 | 
				
			||||||
            msg = "not an McIdas area file"
 | 
					            msg = "not an McIdas area file"
 | 
				
			||||||
            raise SyntaxError(msg)
 | 
					            raise SyntaxError(msg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,16 +57,20 @@ class McIdasImageFile(ImageFile.ImageFile):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # get mode
 | 
					        # get mode
 | 
				
			||||||
        if w[11] == 1:
 | 
					        if w[11] == 1:
 | 
				
			||||||
 | 
					            McIdasImageFile.branches["2"] = True
 | 
				
			||||||
            mode = rawmode = "L"
 | 
					            mode = rawmode = "L"
 | 
				
			||||||
        elif w[11] == 2:
 | 
					        elif w[11] == 2:
 | 
				
			||||||
 | 
					            McIdasImageFile.branches["3"] = True
 | 
				
			||||||
            # FIXME: add memory map support
 | 
					            # FIXME: add memory map support
 | 
				
			||||||
            mode = "I"
 | 
					            mode = "I"
 | 
				
			||||||
            rawmode = "I;16B"
 | 
					            rawmode = "I;16B"
 | 
				
			||||||
        elif w[11] == 4:
 | 
					        elif w[11] == 4:
 | 
				
			||||||
 | 
					            McIdasImageFile.branches["4"] = True
 | 
				
			||||||
            # FIXME: add memory map support
 | 
					            # FIXME: add memory map support
 | 
				
			||||||
            mode = "I"
 | 
					            mode = "I"
 | 
				
			||||||
            rawmode = "I;32B"
 | 
					            rawmode = "I;32B"
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
 | 
					            McIdasImageFile.branches["5"] = True
 | 
				
			||||||
            msg = "unsupported McIdas format"
 | 
					            msg = "unsupported McIdas format"
 | 
				
			||||||
            raise SyntaxError(msg)
 | 
					            raise SyntaxError(msg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -76,3 +89,4 @@ class McIdasImageFile(ImageFile.ImageFile):
 | 
				
			||||||
Image.register_open(McIdasImageFile.format, McIdasImageFile, _accept)
 | 
					Image.register_open(McIdasImageFile.format, McIdasImageFile, _accept)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# no default extension
 | 
					# no default extension
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user