mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-07-04 11:53:32 +03:00
commit
4c61c980ac
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"]
|
|
@ -4,6 +4,8 @@ import sys
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from PIL import PdfParser
|
from PIL import PdfParser
|
||||||
|
from PIL import ImageCms
|
||||||
|
from PIL import McIdasImagePlugin
|
||||||
|
|
||||||
pytest_plugins = ["Tests.helper"]
|
pytest_plugins = ["Tests.helper"]
|
||||||
|
|
||||||
|
@ -12,6 +14,8 @@ def calculate_coverage(test_name):
|
||||||
all_branches = {
|
all_branches = {
|
||||||
"branches1": Image.branches,
|
"branches1": Image.branches,
|
||||||
"branches2": PdfParser.XrefTable.branches,
|
"branches2": PdfParser.XrefTable.branches,
|
||||||
|
"branches3": ImageCms.ImageCmsProfile.branches,
|
||||||
|
"branches4": McIdasImagePlugin.McIdasImageFile.branches,
|
||||||
# Add more
|
# Add more
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,5 +50,3 @@ def pytest_sessionfinish(session, exitstatus):
|
||||||
|
|
||||||
coverage = calculate_coverage(test_name)
|
coverage = calculate_coverage(test_name)
|
||||||
print("\nBRANCH COVERAGE for", test_name, ":", coverage, "%\n")
|
print("\nBRANCH COVERAGE for", test_name, ":", coverage, "%\n")
|
||||||
|
|
||||||
|
|
|
@ -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