mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-01 04:46:18 +03:00
Improve handling of PPM headers
This commit is contained in:
parent
396b329507
commit
6b81e34d67
|
@ -20,7 +20,7 @@ from . import Image, ImageFile
|
||||||
#
|
#
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
|
|
||||||
b_whitespace = b"\x20\x09\x0a\x0b\x0c\x0d"
|
B_WHITESPACE = b"\x20\x09\x0a\x0b\x0c\x0d"
|
||||||
|
|
||||||
MODES = {
|
MODES = {
|
||||||
# standard
|
# standard
|
||||||
|
@ -49,25 +49,39 @@ class PpmImageFile(ImageFile.ImageFile):
|
||||||
format = "PPM"
|
format = "PPM"
|
||||||
format_description = "Pbmplus image"
|
format_description = "Pbmplus image"
|
||||||
|
|
||||||
def _token(self, s=b""):
|
def _read_token(self, token=b""):
|
||||||
|
def _ignore_comment(): # ignores rest of the line; stops at CR, LF or EOF
|
||||||
|
while True:
|
||||||
|
c = self.fp.read(1)
|
||||||
|
if c in b"\r\n":
|
||||||
|
break
|
||||||
|
|
||||||
|
while True: # read until non-whitespace is found
|
||||||
|
c = self.fp.read(1)
|
||||||
|
if c == b"#": # found comment, ignore it
|
||||||
|
_ignore_comment()
|
||||||
|
continue
|
||||||
|
if c in B_WHITESPACE: # found whitespace, ignore it
|
||||||
|
if c == b"": # reached EOF
|
||||||
|
raise EOFError("Reached EOF while reading header")
|
||||||
|
continue
|
||||||
|
break
|
||||||
|
|
||||||
|
token += c
|
||||||
|
|
||||||
while True: # read until next whitespace
|
while True: # read until next whitespace
|
||||||
c = self.fp.read(1)
|
c = self.fp.read(1)
|
||||||
if not c or c in b_whitespace:
|
if c == b"#":
|
||||||
|
_ignore_comment()
|
||||||
|
continue
|
||||||
|
if c in B_WHITESPACE: # token ended
|
||||||
break
|
break
|
||||||
if c > b"\x79":
|
token += c
|
||||||
raise ValueError("Expected ASCII value, found binary")
|
return token
|
||||||
s = s + c
|
|
||||||
if len(s) > 9:
|
|
||||||
raise ValueError("Expected int, got > 9 digits")
|
|
||||||
return s
|
|
||||||
|
|
||||||
def _open(self):
|
def _open(self):
|
||||||
|
P = self.fp.read(1)
|
||||||
# check magic
|
magic_number = self._read_token(P)
|
||||||
s = self.fp.read(1)
|
|
||||||
if s != b"P":
|
|
||||||
raise SyntaxError("not a PPM file")
|
|
||||||
magic_number = self._token(s)
|
|
||||||
mode = MODES[magic_number]
|
mode = MODES[magic_number]
|
||||||
|
|
||||||
self.custom_mimetype = {
|
self.custom_mimetype = {
|
||||||
|
@ -83,29 +97,21 @@ class PpmImageFile(ImageFile.ImageFile):
|
||||||
self.mode = rawmode = mode
|
self.mode = rawmode = mode
|
||||||
|
|
||||||
for ix in range(3):
|
for ix in range(3):
|
||||||
while True:
|
try: # check token sanity
|
||||||
while True:
|
token = int(self._read_token())
|
||||||
s = self.fp.read(1)
|
except ValueError:
|
||||||
if s not in b_whitespace:
|
raise SyntaxError("Non-decimal-ASCII found in header")
|
||||||
break
|
if ix == 0: # token is the x size
|
||||||
if s == b"":
|
xsize = token
|
||||||
raise ValueError("File does not extend beyond magic number")
|
elif ix == 1: # token is the y size
|
||||||
if s != b"#":
|
ysize = token
|
||||||
break
|
|
||||||
s = self.fp.readline()
|
|
||||||
s = int(self._token(s))
|
|
||||||
if ix == 0:
|
|
||||||
xsize = s
|
|
||||||
elif ix == 1:
|
|
||||||
ysize = s
|
|
||||||
if mode == "1":
|
if mode == "1":
|
||||||
break
|
break
|
||||||
elif ix == 2:
|
elif ix == 2: # token is maxval
|
||||||
# maxgrey
|
if token > 255:
|
||||||
if s > 255:
|
|
||||||
if not mode == "L":
|
if not mode == "L":
|
||||||
raise ValueError(f"Too many colors for band: {s}")
|
raise SyntaxError(f"Too many colors for band: {token}")
|
||||||
if s < 2 ** 16:
|
if token < 2 ** 16:
|
||||||
self.mode = "I"
|
self.mode = "I"
|
||||||
rawmode = "I;16B"
|
rawmode = "I;16B"
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user