Skip to content

Commit

Permalink
Resolved FIXME by reading mandatory FITS header items
Browse files Browse the repository at this point in the history
  • Loading branch information
radarhere committed Apr 14, 2021
1 parent 45003b7 commit ab4835c
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 14 deletions.
Binary file added Tests/images/hopper_naxis_zero.fits
Binary file not shown.
23 changes: 19 additions & 4 deletions Tests/test_file_fitsstub.py
@@ -1,3 +1,5 @@
from io import BytesIO

import pytest

from PIL import FitsStubImagePlugin, Image
Expand All @@ -11,10 +13,8 @@ def test_open():

# Assert
assert im.format == "FITS"

# Dummy data from the stub
assert im.mode == "F"
assert im.size == (1, 1)
assert im.size == (128, 128)
assert im.mode == "L"


def test_invalid_file():
Expand All @@ -35,6 +35,21 @@ def test_load():
im.load()


def test_truncated_fits():
# No END to headers
image_data = b"SIMPLE = T" + b" " * 50 + b"TRUNCATE"
with pytest.raises(OSError):
FitsStubImagePlugin.FITSStubImageFile(BytesIO(image_data))


def test_naxis_zero():
# This test image has been manually hexedited
# to set the number of data axes to zero
with pytest.raises(ValueError):
with Image.open("Tests/images/hopper_naxis_zero.fits"):
pass


def test_save():
# Arrange
with Image.open(TEST_FILE) as im:
Expand Down
45 changes: 35 additions & 10 deletions src/PIL/FitsStubImagePlugin.py
Expand Up @@ -38,21 +38,46 @@ class FITSStubImageFile(ImageFile.StubImageFile):
format_description = "FITS"

def _open(self):

offset = self.fp.tell()

if not _accept(self.fp.read(6)):
raise SyntaxError("Not a FITS file")

# FIXME: add more sanity checks here; mandatory header items
# include SIMPLE, BITPIX, NAXIS, etc.
headers = {}
while True:
header = self.fp.read(80)
if not header:
raise OSError("Truncated FITS file")
break
keyword = header[:8].strip()
if keyword == b"END":
break
value = header[8:].strip()
if value.startswith(b"="):
value = value[1:].strip()
if not headers and (not _accept(keyword) or value != b"T"):
raise SyntaxError("Not a FITS file")
headers[keyword] = value

naxis = int(headers[b"NAXIS"])
if naxis == 0:
raise ValueError("No image data")
elif naxis == 1:
self._size = 1, int(headers[b"NAXIS1"])
else:
self._size = int(headers[b"NAXIS1"]), int(headers[b"NAXIS2"])

number_of_bits = int(headers[b"BITPIX"])
if number_of_bits == 8:
self.mode = "L"
elif number_of_bits == 16:
self.mode = "I"
# rawmode = "I;16S"
elif number_of_bits == 32:
self.mode = "I"
elif number_of_bits in (-32, -64):
self.mode = "F"
# rawmode = "F" if number_of_bits == -32 else "F;64F"

self.fp.seek(offset)

# make something up
self.mode = "F"
self._size = 1, 1

loader = self._load()
if loader:
loader.open(self)
Expand Down

0 comments on commit ab4835c

Please sign in to comment.