Merge pull request #1 from radarhere/parse-eps-trailer

Last trailer comment has priority
This commit is contained in:
nopperl 2023-09-23 06:41:59 +00:00 committed by GitHub
commit b21ea55beb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 48 deletions

Binary file not shown.

Binary file not shown.

View File

@ -406,10 +406,16 @@ def test_timeout(test_file):
pass
def test_boundary_box_in_trailer():
# Check whether boundary boxes are parsed in the same way
# when specified in the header or the trailer
def test_bounding_box_in_trailer():
# Check bounding boxes are parsed in the same way
# when specified in the header and the trailer
with Image.open("Tests/images/zero_bb_trailer.eps") as trailer_image, Image.open(
FILE1
) as header_image:
assert trailer_image.size == header_image.size
def test_eof_before_bounding_box():
with pytest.raises(OSError):
with Image.open("Tests/images/zero_bb_eof_before_boundingbox.eps"):
pass

View File

@ -245,6 +245,34 @@ class EpsImageFile(ImageFile.ImageFile):
msg = 'EPS header missing "%%BoundingBox" comment'
raise SyntaxError(msg)
def _read_comment(s):
nonlocal reading_trailer_comments
try:
m = split.match(s)
except re.error as e:
msg = "not an EPS file"
raise SyntaxError(msg) from e
if m:
k, v = m.group(1, 2)
self.info[k] = v
if k == "BoundingBox":
if v == "(atend)":
reading_trailer_comments = True
elif not self._size or reading_trailer_comments:
try:
# Note: The DSC spec says that BoundingBox
# fields should be integers, but some drivers
# put floating point values there anyway.
box = [int(float(i)) for i in v.split()]
self._size = box[2] - box[0], box[3] - box[1]
self.tile = [
("eps", (0, 0) + self.size, offset, (length, box))
]
except Exception:
pass
return True
while True:
byte = self.fp.read(1)
if byte == b"":
@ -289,22 +317,7 @@ class EpsImageFile(ImageFile.ImageFile):
continue
s = str(bytes_mv[:bytes_read], "latin-1")
try:
m = split.match(s)
except re.error as e:
msg = "not an EPS file"
raise SyntaxError(msg) from e
if m:
k, v = m.group(1, 2)
self.info[k] = v
if k == "BoundingBox":
if v == "(atend)":
reading_trailer_comments = True
else:
self._read_boundary_box(v, offset, length)
else:
if not _read_comment(s):
m = field.match(s)
if m:
k = m.group(1)
@ -354,27 +367,13 @@ class EpsImageFile(ImageFile.ImageFile):
# Load EPS trailer
# if this line starts with "%%EOF",
# then we've reached the end of the trailer
# then we've reached the end of the file
if bytes_mv[:5] == b"%%EOF":
reading_trailer_comments = False
continue
break
s = str(bytes_mv[:bytes_read], "latin-1")
try:
m = split.match(s)
except re.error as e:
msg = "not an EPS file"
raise SyntaxError(msg) from e
if m:
k, v = m.group(1, 2)
self.info[k] = v
if k == "BoundingBox":
if not self._size:
self._read_boundary_box(v, offset, length)
if bytes_mv[:9] == b"%%Trailer":
_read_comment(s)
elif bytes_mv[:9] == b"%%Trailer":
trailer_reached = True
bytes_read = 0
@ -407,17 +406,6 @@ class EpsImageFile(ImageFile.ImageFile):
return length, offset
def _read_boundary_box(self, v, offset, length):
try:
# Note: The DSC spec says that BoundingBox
# fields should be integers, but some drivers
# put floating point values there anyway.
box = [int(float(i)) for i in v.split()]
self._size = box[2] - box[0], box[3] - box[1]
self.tile = [("eps", (0, 0) + self.size, offset, (length, box))]
except Exception:
pass
def load(self, scale=1, transparency=False):
# Load EPS via Ghostscript
if self.tile: