Skip to content

Commit 605e664

Browse files
authored
Merge pull request #7698 from radarhere/ppm
2 parents 35d6a66 + 6c32032 commit 605e664

1 file changed

Lines changed: 31 additions & 40 deletions

File tree

src/PIL/PpmImagePlugin.py

Lines changed: 31 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ def _open(self):
100100
except KeyError:
101101
msg = "not a PPM file"
102102
raise SyntaxError(msg)
103+
self._mode = mode
103104

104105
if magic_number in (b"P1", b"P4"):
105106
self.custom_mimetype = "image/x-portable-bitmap"
@@ -108,49 +109,40 @@ def _open(self):
108109
elif magic_number in (b"P3", b"P6"):
109110
self.custom_mimetype = "image/x-portable-pixmap"
110111

111-
maxval = None
112+
self._size = int(self._read_token()), int(self._read_token())
113+
112114
decoder_name = "raw"
113115
if magic_number in (b"P1", b"P2", b"P3"):
114116
decoder_name = "ppm_plain"
115-
for ix in range(3):
116-
if mode == "F" and ix == 2:
117-
scale = float(self._read_token())
118-
if scale == 0.0 or not math.isfinite(scale):
119-
msg = "scale must be finite and non-zero"
120-
raise ValueError(msg)
121-
rawmode = "F;32F" if scale < 0 else "F;32BF"
122-
self.info["scale"] = abs(scale)
123-
continue
124-
token = int(self._read_token())
125-
if ix == 0: # token is the x size
126-
xsize = token
127-
elif ix == 1: # token is the y size
128-
ysize = token
129-
if mode == "1":
130-
self._mode = "1"
131-
rawmode = "1;I"
132-
break
133-
else:
134-
self._mode = rawmode = mode
135-
elif ix == 2: # token is maxval
136-
maxval = token
137-
if not 0 < maxval < 65536:
138-
msg = "maxval must be greater than 0 and less than 65536"
139-
raise ValueError(msg)
140-
if maxval > 255 and mode == "L":
141-
self._mode = "I"
117+
if mode == "1":
118+
args = "1;I"
119+
elif mode == "F":
120+
scale = float(self._read_token())
121+
if scale == 0.0 or not math.isfinite(scale):
122+
msg = "scale must be finite and non-zero"
123+
raise ValueError(msg)
124+
self.info["scale"] = abs(scale)
125+
126+
rawmode = "F;32F" if scale < 0 else "F;32BF"
127+
args = (rawmode, 0, -1)
128+
else:
129+
maxval = int(self._read_token())
130+
if not 0 < maxval < 65536:
131+
msg = "maxval must be greater than 0 and less than 65536"
132+
raise ValueError(msg)
133+
if maxval > 255 and mode == "L":
134+
self._mode = "I"
142135

143-
if decoder_name != "ppm_plain":
144-
# If maxval matches a bit depth, use the raw decoder directly
145-
if maxval == 65535 and mode == "L":
146-
rawmode = "I;16B"
147-
elif maxval != 255:
148-
decoder_name = "ppm"
136+
rawmode = mode
137+
if decoder_name != "ppm_plain":
138+
# If maxval matches a bit depth, use the raw decoder directly
139+
if maxval == 65535 and mode == "L":
140+
rawmode = "I;16B"
141+
elif maxval != 255:
142+
decoder_name = "ppm"
149143

150-
row_order = -1 if mode == "F" else 1
151-
args = (rawmode, 0, row_order) if decoder_name == "raw" else (rawmode, maxval)
152-
self._size = xsize, ysize
153-
self.tile = [(decoder_name, (0, 0, xsize, ysize), self.fp.tell(), args)]
144+
args = rawmode if decoder_name == "raw" else (rawmode, maxval)
145+
self.tile = [(decoder_name, (0, 0) + self.size, self.fp.tell(), args)]
154146

155147

156148
#
@@ -319,7 +311,6 @@ def decode(self, buffer):
319311

320312

321313
def _save(im, fp, filename):
322-
row_order = 1
323314
if im.mode == "1":
324315
rawmode, head = "1;I", b"P4"
325316
elif im.mode == "L":
@@ -330,7 +321,6 @@ def _save(im, fp, filename):
330321
rawmode, head = "RGB", b"P6"
331322
elif im.mode == "F":
332323
rawmode, head = "F;32F", b"Pf"
333-
row_order = -1
334324
else:
335325
msg = f"cannot write mode {im.mode} as PPM"
336326
raise OSError(msg)
@@ -344,6 +334,7 @@ def _save(im, fp, filename):
344334
fp.write(b"65535\n")
345335
elif head == b"Pf":
346336
fp.write(b"-1.0\n")
337+
row_order = -1 if im.mode == "F" else 1
347338
ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, 0, row_order))])
348339

349340

0 commit comments

Comments
 (0)