mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-24 17:06:16 +03:00
add EPS test for image with ImageData and BoundingBox (atend)
This commit is contained in:
parent
00bbd4a5b9
commit
6b168a3e2b
BIN
Tests/images/eps/1_atend.eps
Normal file
BIN
Tests/images/eps/1_atend.eps
Normal file
Binary file not shown.
|
@ -127,6 +127,15 @@ def test_binary_header_only() -> None:
|
||||||
EpsImagePlugin.EpsImageFile(data)
|
EpsImagePlugin.EpsImageFile(data)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("prefix", (b"", simple_binary_header))
|
||||||
|
def test_simple_eps_file(prefix: bytes) -> None:
|
||||||
|
data = io.BytesIO(prefix + b"\n".join(simple_eps_file))
|
||||||
|
with Image.open(data) as img:
|
||||||
|
assert img.mode == "RGB"
|
||||||
|
assert img.size == (100, 100)
|
||||||
|
assert img.format == "EPS"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("prefix", (b"", simple_binary_header))
|
@pytest.mark.parametrize("prefix", (b"", simple_binary_header))
|
||||||
def test_missing_version_comment(prefix: bytes) -> None:
|
def test_missing_version_comment(prefix: bytes) -> None:
|
||||||
data = io.BytesIO(prefix + b"\n".join(simple_eps_file_without_version))
|
data = io.BytesIO(prefix + b"\n".join(simple_eps_file_without_version))
|
||||||
|
@ -142,23 +151,19 @@ def test_missing_boundingbox_comment(prefix: bytes) -> None:
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("prefix", (b"", simple_binary_header))
|
@pytest.mark.parametrize("prefix", (b"", simple_binary_header))
|
||||||
def test_invalid_boundingbox_comment(prefix: bytes) -> None:
|
@pytest.mark.parametrize(
|
||||||
data = io.BytesIO(prefix + b"\n".join(simple_eps_file_with_invalid_boundingbox))
|
"file_lines",
|
||||||
|
(
|
||||||
|
simple_eps_file_with_invalid_boundingbox,
|
||||||
|
simple_eps_file_with_invalid_boundingbox_valid_imagedata,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
def test_invalid_boundingbox_comment(prefix: bytes, file_lines: list[bytes]) -> None:
|
||||||
|
data = io.BytesIO(prefix + b"\n".join(file_lines))
|
||||||
with pytest.raises(OSError, match="cannot determine EPS bounding box"):
|
with pytest.raises(OSError, match="cannot determine EPS bounding box"):
|
||||||
EpsImagePlugin.EpsImageFile(data)
|
EpsImagePlugin.EpsImageFile(data)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("prefix", (b"", simple_binary_header))
|
|
||||||
def test_invalid_boundingbox_comment_valid_imagedata_comment(prefix: bytes) -> None:
|
|
||||||
data = io.BytesIO(
|
|
||||||
prefix + b"\n".join(simple_eps_file_with_invalid_boundingbox_valid_imagedata)
|
|
||||||
)
|
|
||||||
with Image.open(data) as img:
|
|
||||||
assert img.mode == "RGB"
|
|
||||||
assert img.size == (100, 100)
|
|
||||||
assert img.format == "EPS"
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("prefix", (b"", simple_binary_header))
|
@pytest.mark.parametrize("prefix", (b"", simple_binary_header))
|
||||||
def test_ascii_comment_too_long(prefix: bytes) -> None:
|
def test_ascii_comment_too_long(prefix: bytes) -> None:
|
||||||
data = io.BytesIO(prefix + b"\n".join(simple_eps_file_with_long_ascii_comment))
|
data = io.BytesIO(prefix + b"\n".join(simple_eps_file_with_long_ascii_comment))
|
||||||
|
@ -247,8 +252,13 @@ def test_bytesio_object() -> None:
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(not HAS_GHOSTSCRIPT, reason="Ghostscript not available")
|
@pytest.mark.skipif(not HAS_GHOSTSCRIPT, reason="Ghostscript not available")
|
||||||
def test_1() -> None:
|
@pytest.mark.parametrize(
|
||||||
with Image.open("Tests/images/eps/1.eps") as im:
|
# These images have an "ImageData" descriptor.
|
||||||
|
"filename",
|
||||||
|
("Tests/images/eps/1.eps", "Tests/images/eps/1_atend.eps"),
|
||||||
|
)
|
||||||
|
def test_1(filename: str) -> None:
|
||||||
|
with Image.open(filename) as im:
|
||||||
assert_image_equal_tofile(im, "Tests/images/eps/1.bmp")
|
assert_image_equal_tofile(im, "Tests/images/eps/1.bmp")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -194,6 +194,11 @@ class EpsImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
self._mode = "RGB"
|
self._mode = "RGB"
|
||||||
|
|
||||||
|
# When reading header comments, the first comment is used.
|
||||||
|
# When reading trailer comments, the last comment is used.
|
||||||
|
bounding_box: list[int] | None = None
|
||||||
|
imagedata_size: tuple[int, int] | None = None
|
||||||
|
|
||||||
byte_arr = bytearray(255)
|
byte_arr = bytearray(255)
|
||||||
bytes_mv = memoryview(byte_arr)
|
bytes_mv = memoryview(byte_arr)
|
||||||
bytes_read = 0
|
bytes_read = 0
|
||||||
|
@ -214,8 +219,8 @@ class EpsImageFile(ImageFile.ImageFile):
|
||||||
msg = 'EPS header missing "%%BoundingBox" comment'
|
msg = 'EPS header missing "%%BoundingBox" comment'
|
||||||
raise SyntaxError(msg)
|
raise SyntaxError(msg)
|
||||||
|
|
||||||
def _read_comment(s: str) -> bool:
|
def read_comment(s: str) -> bool:
|
||||||
nonlocal reading_trailer_comments
|
nonlocal bounding_box, reading_trailer_comments
|
||||||
try:
|
try:
|
||||||
m = split.match(s)
|
m = split.match(s)
|
||||||
except re.error as e:
|
except re.error as e:
|
||||||
|
@ -230,18 +235,12 @@ class EpsImageFile(ImageFile.ImageFile):
|
||||||
if k == "BoundingBox":
|
if k == "BoundingBox":
|
||||||
if v == "(atend)":
|
if v == "(atend)":
|
||||||
reading_trailer_comments = True
|
reading_trailer_comments = True
|
||||||
elif not self.tile or (trailer_reached and reading_trailer_comments):
|
elif not bounding_box or (trailer_reached and reading_trailer_comments):
|
||||||
try:
|
try:
|
||||||
# Note: The DSC spec says that BoundingBox
|
# Note: The DSC spec says that BoundingBox
|
||||||
# fields should be integers, but some drivers
|
# fields should be integers, but some drivers
|
||||||
# put floating point values there anyway.
|
# put floating point values there anyway.
|
||||||
box = [int(float(i)) for i in v.split()]
|
bounding_box = [int(float(i)) for i in v.split()]
|
||||||
self._size = box[2] - box[0], box[3] - box[1]
|
|
||||||
self.tile = [
|
|
||||||
ImageFile._Tile(
|
|
||||||
"eps", (0, 0) + self.size, offset, (length, box)
|
|
||||||
)
|
|
||||||
]
|
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
return True
|
return True
|
||||||
|
@ -292,7 +291,7 @@ class EpsImageFile(ImageFile.ImageFile):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
s = str(bytes_mv[:bytes_read], "latin-1")
|
s = str(bytes_mv[:bytes_read], "latin-1")
|
||||||
if not _read_comment(s):
|
if not read_comment(s):
|
||||||
m = field.match(s)
|
m = field.match(s)
|
||||||
if m:
|
if m:
|
||||||
k = m.group(1)
|
k = m.group(1)
|
||||||
|
@ -326,32 +325,50 @@ class EpsImageFile(ImageFile.ImageFile):
|
||||||
int(value) for value in image_data_values[:4]
|
int(value) for value in image_data_values[:4]
|
||||||
)
|
)
|
||||||
|
|
||||||
if bit_depth == 1:
|
if not imagedata_size:
|
||||||
self._mode = "1"
|
imagedata_size = columns, rows
|
||||||
elif bit_depth == 8:
|
|
||||||
try:
|
|
||||||
self._mode = self.mode_map[mode_id]
|
|
||||||
except ValueError:
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
|
|
||||||
self._size = columns, rows
|
if bit_depth == 1:
|
||||||
return
|
self._mode = "1"
|
||||||
|
elif bit_depth == 8:
|
||||||
|
try:
|
||||||
|
self._mode = self.mode_map[mode_id]
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
elif bytes_mv[:5] == b"%%EOF":
|
elif bytes_mv[:5] == b"%%EOF":
|
||||||
break
|
break
|
||||||
elif trailer_reached and reading_trailer_comments:
|
elif trailer_reached and reading_trailer_comments:
|
||||||
# Load EPS trailer
|
# Load EPS trailer
|
||||||
s = str(bytes_mv[:bytes_read], "latin-1")
|
s = str(bytes_mv[:bytes_read], "latin-1")
|
||||||
_read_comment(s)
|
read_comment(s)
|
||||||
elif bytes_mv[:9] == b"%%Trailer":
|
elif bytes_mv[:9] == b"%%Trailer":
|
||||||
trailer_reached = True
|
trailer_reached = True
|
||||||
bytes_read = 0
|
bytes_read = 0
|
||||||
|
|
||||||
if not self.tile:
|
# A "BoundingBox" is always required,
|
||||||
|
# even if an "ImageData" descriptor size exists.
|
||||||
|
if not bounding_box:
|
||||||
msg = "cannot determine EPS bounding box"
|
msg = "cannot determine EPS bounding box"
|
||||||
raise OSError(msg)
|
raise OSError(msg)
|
||||||
|
|
||||||
|
# An "ImageData" size takes precedence over the "BoundingBox".
|
||||||
|
if imagedata_size:
|
||||||
|
self._size = imagedata_size
|
||||||
|
else:
|
||||||
|
self._size = (
|
||||||
|
bounding_box[2] - bounding_box[0],
|
||||||
|
bounding_box[3] - bounding_box[1],
|
||||||
|
)
|
||||||
|
|
||||||
|
self.tile = [
|
||||||
|
ImageFile._Tile(
|
||||||
|
codec_name="eps",
|
||||||
|
extents=(0, 0) + self._size,
|
||||||
|
offset=offset,
|
||||||
|
args=(length, bounding_box),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
def _find_offset(self, fp: IO[bytes]) -> tuple[int, int]:
|
def _find_offset(self, fp: IO[bytes]) -> tuple[int, int]:
|
||||||
s = fp.read(4)
|
s = fp.read(4)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user