Merge branch 'main' into isidora

This commit is contained in:
daraccrafter 2024-06-22 16:12:59 +02:00
commit 1ef7b9c9ba
6 changed files with 128 additions and 30 deletions

View 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()

View File

@ -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])

View 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"]

View File

@ -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
} }

View File

@ -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

View File

@ -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