Skip to content

Commit 372dd2b

Browse files
committed
Treat data as big-endian
1 parent 43b6480 commit 372dd2b

2 files changed

Lines changed: 31 additions & 5 deletions

File tree

Tests/test_file_fits.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ def test_open() -> None:
2424

2525
def test_gzip1() -> None:
2626
with Image.open("Tests/images/m13_gzip.fits") as im:
27+
assert im.getpixel((0, 0)) == 111
28+
2729
assert_image_equal_tofile(im, "Tests/images/m13.fits")
2830

2931

@@ -36,6 +38,22 @@ def test_invalid_file() -> None:
3638
FitsImagePlugin.FitsImageFile(invalid_file)
3739

3840

41+
def test_unsupported_number_of_bits() -> None:
42+
image_data = b"".join(
43+
data.ljust(80, b" ")
44+
for data in [
45+
b"SIMPLE = T",
46+
b"BITPIX = 128",
47+
b"NAXIS = 1",
48+
b"NAXIS1 = 0",
49+
b"END",
50+
]
51+
)
52+
with pytest.raises(OSError, match="Unsupported number of bits"):
53+
with Image.open(BytesIO(image_data)):
54+
pass
55+
56+
3957
def test_truncated_fits() -> None:
4058
# No END to headers
4159
image_data = b"SIMPLE = T" + b" " * 50 + b"TRUNCATE"

src/PIL/FitsImagePlugin.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,17 +107,23 @@ def _parse_headers(
107107

108108
number_of_bits = int(headers[prefix + b"BITPIX"])
109109
if number_of_bits == 8:
110-
self._mode = "L"
110+
self._mode = rawmode = "L"
111111
elif number_of_bits == 16:
112112
self._mode = "I;16"
113+
rawmode = "I;16B"
113114
elif number_of_bits == 32:
114115
self._mode = "I"
115-
elif number_of_bits in (-32, -64):
116+
rawmode = "I;32B"
117+
elif number_of_bits == -32:
116118
self._mode = "F"
119+
rawmode = "F;32B"
120+
else:
121+
msg = "Unsupported number of bits"
122+
raise OSError(msg)
117123

118124
args: tuple[str | int, ...]
119125
if decoder_name == "raw":
120-
args = (self.mode, 0, -1)
126+
args = (rawmode, 0, -1)
121127
else:
122128
args = (number_of_bits,)
123129
return decoder_name, offset, args
@@ -133,11 +139,13 @@ def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int
133139

134140
rows = []
135141
offset = 0
136-
number_of_bits = min(self.args[0] // 8, 4)
142+
number_of_bits = abs(self.args[0]) // 8
137143
for y in range(self.state.ysize):
138144
row = bytearray()
139145
for x in range(self.state.xsize):
140-
row += value[offset + (4 - number_of_bits) : offset + 4]
146+
row += value[
147+
offset + 4 - 1 : offset + (4 - number_of_bits) - 1 : -1
148+
]
141149
offset += 4
142150
rows.append(row)
143151
self.set_as_raw(bytes([pixel for row in rows[::-1] for pixel in row]))

0 commit comments

Comments
 (0)