Skip to content

Commit e783aff

Browse files
authored
Improve SgiImagePlugin test coverage (#8896)
1 parent 1788ab7 commit e783aff

File tree

2 files changed

+25
-23
lines changed

2 files changed

+25
-23
lines changed

Tests/test_file_sgi.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
from io import BytesIO
34
from pathlib import Path
45

56
import pytest
@@ -71,6 +72,15 @@ def test_invalid_file() -> None:
7172
SgiImagePlugin.SgiImageFile(invalid_file)
7273

7374

75+
def test_unsupported_image_mode() -> None:
76+
with open("Tests/images/hopper.rgb", "rb") as fp:
77+
data = fp.read()
78+
data = data[:3] + b"\x03" + data[4:]
79+
with pytest.raises(ValueError, match="Unsupported SGI image mode"):
80+
with Image.open(BytesIO(data)):
81+
pass
82+
83+
7484
def roundtrip(img: Image.Image, tmp_path: Path) -> None:
7585
out = tmp_path / "temp.sgi"
7686
img.save(out, format="sgi")
@@ -109,3 +119,11 @@ def test_unsupported_mode(tmp_path: Path) -> None:
109119

110120
with pytest.raises(ValueError):
111121
im.save(out, format="sgi")
122+
123+
124+
def test_unsupported_number_of_bytes_per_pixel(tmp_path: Path) -> None:
125+
im = hopper()
126+
out = tmp_path / "temp.sgi"
127+
128+
with pytest.raises(ValueError, match="Unsupported number of bytes per pixel"):
129+
im.save(out, bpc=3)

src/PIL/SgiImagePlugin.py

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -82,17 +82,10 @@ def _open(self) -> None:
8282
# zsize : channels count
8383
zsize = i16(s, 10)
8484

85-
# layout
86-
layout = bpc, dimension, zsize
87-
8885
# determine mode from bits/zsize
89-
rawmode = ""
9086
try:
91-
rawmode = MODES[layout]
87+
rawmode = MODES[(bpc, dimension, zsize)]
9288
except KeyError:
93-
pass
94-
95-
if rawmode == "":
9689
msg = "Unsupported SGI image mode"
9790
raise ValueError(msg)
9891

@@ -156,24 +149,15 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
156149
# Run-Length Encoding Compression - Unsupported at this time
157150
rle = 0
158151

159-
# Number of dimensions (x,y,z)
160-
dim = 3
161152
# X Dimension = width / Y Dimension = height
162153
x, y = im.size
163-
if im.mode == "L" and y == 1:
164-
dim = 1
165-
elif im.mode == "L":
166-
dim = 2
167154
# Z Dimension: Number of channels
168155
z = len(im.mode)
169-
170-
if dim in {1, 2}:
171-
z = 1
172-
173-
# assert we've got the right number of bands.
174-
if len(im.getbands()) != z:
175-
msg = f"incorrect number of bands in SGI write: {z} vs {len(im.getbands())}"
176-
raise ValueError(msg)
156+
# Number of dimensions (x,y,z)
157+
if im.mode == "L":
158+
dimension = 1 if y == 1 else 2
159+
else:
160+
dimension = 3
177161

178162
# Minimum Byte value
179163
pinmin = 0
@@ -188,7 +172,7 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
188172
fp.write(struct.pack(">h", magic_number))
189173
fp.write(o8(rle))
190174
fp.write(o8(bpc))
191-
fp.write(struct.pack(">H", dim))
175+
fp.write(struct.pack(">H", dimension))
192176
fp.write(struct.pack(">H", x))
193177
fp.write(struct.pack(">H", y))
194178
fp.write(struct.pack(">H", z))

0 commit comments

Comments
 (0)