@@ -193,7 +193,11 @@ def _open(self) -> None:
193193 self .fp .seek (offset )
194194
195195 self ._mode = "RGB"
196- self ._size = None
196+
197+ # The last occurrence of one of these values
198+ # takes precedence over prior occurrences.
199+ bounding_box = None
200+ imagedata_size = None
197201
198202 byte_arr = bytearray (255 )
199203 bytes_mv = memoryview (byte_arr )
@@ -215,8 +219,8 @@ def check_required_header_comments() -> None:
215219 msg = 'EPS header missing "%%BoundingBox" comment'
216220 raise SyntaxError (msg )
217221
218- def _read_comment (s : str ) -> bool :
219- nonlocal reading_trailer_comments
222+ def read_comment (s : str ) -> bool :
223+ nonlocal bounding_box , reading_trailer_comments
220224 try :
221225 m = split .match (s )
222226 except re .error as e :
@@ -231,18 +235,12 @@ def _read_comment(s: str) -> bool:
231235 if k == "BoundingBox" :
232236 if v == "(atend)" :
233237 reading_trailer_comments = True
234- elif not self . _size or ( trailer_reached and reading_trailer_comments ) :
238+ else :
235239 try :
236240 # Note: The DSC spec says that BoundingBox
237241 # fields should be integers, but some drivers
238242 # put floating point values there anyway.
239- box = [int (float (i )) for i in v .split ()]
240- self ._size = box [2 ] - box [0 ], box [3 ] - box [1 ]
241- self .tile = [
242- ImageFile ._Tile (
243- "eps" , (0 , 0 ) + self .size , offset , (length , box )
244- )
245- ]
243+ bounding_box = [int (float (i )) for i in v .split ()]
246244 except Exception :
247245 pass
248246 return True
@@ -293,7 +291,7 @@ def _read_comment(s: str) -> bool:
293291 continue
294292
295293 s = str (bytes_mv [:bytes_read ], "latin-1" )
296- if not _read_comment (s ):
294+ if not read_comment (s ):
297295 m = field .match (s )
298296 if m :
299297 k = m .group (1 )
@@ -327,32 +325,51 @@ def _read_comment(s: str) -> bool:
327325 int (value ) for value in image_data_values [:4 ]
328326 )
329327
328+ imagedata_size = (columns , rows )
329+
330330 if bit_depth == 1 :
331331 self ._mode = "1"
332332 elif bit_depth == 8 :
333333 try :
334334 self ._mode = self .mode_map [mode_id ]
335335 except ValueError :
336- break
336+ pass
337337 else :
338- break
339-
340- self ._size = columns , rows
341- return
338+ pass
342339 elif bytes_mv [:5 ] == b"%%EOF" :
343340 break
344341 elif trailer_reached and reading_trailer_comments :
345342 # Load EPS trailer
346343 s = str (bytes_mv [:bytes_read ], "latin-1" )
347- _read_comment (s )
344+ read_comment (s )
348345 elif bytes_mv [:9 ] == b"%%Trailer" :
349346 trailer_reached = True
350347 bytes_read = 0
351348
352- if not self ._size :
349+ # A "BoundingBox" is always required,
350+ # even if an "ImageData" descriptor size exists.
351+ if not bounding_box :
353352 msg = "cannot determine EPS bounding box"
354353 raise OSError (msg )
355354
355+ # An "ImageData" size takes precedence over the "BoundingBox".
356+ if imagedata_size :
357+ self ._size = imagedata_size
358+ else :
359+ self ._size = (
360+ bounding_box [2 ] - bounding_box [0 ],
361+ bounding_box [3 ] - bounding_box [1 ],
362+ )
363+
364+ self .tile = [
365+ ImageFile ._Tile (
366+ codec_name = "eps" ,
367+ extents = (0 , 0 ) + self ._size ,
368+ offset = offset ,
369+ args = (length , bounding_box ),
370+ )
371+ ]
372+
356373 def _find_offset (self , fp : IO [bytes ]) -> tuple [int , int ]:
357374 s = fp .read (4 )
358375
0 commit comments