diff --git a/Tests/images/hopper.fits b/Tests/images/hopper.fits index 85afa4ac1..7f28f75e5 100644 Binary files a/Tests/images/hopper.fits and b/Tests/images/hopper.fits differ diff --git a/Tests/test_file_fitsstub.py b/Tests/test_file_fits.py similarity index 51% rename from Tests/test_file_fitsstub.py rename to Tests/test_file_fits.py index c77457947..68d708fb1 100644 --- a/Tests/test_file_fitsstub.py +++ b/Tests/test_file_fits.py @@ -2,7 +2,9 @@ from io import BytesIO import pytest -from PIL import FitsStubImagePlugin, Image +from PIL import FitsImagePlugin, Image + +from .helper import assert_image_equal, hopper TEST_FILE = "Tests/images/hopper.fits" @@ -16,6 +18,8 @@ def test_open(): assert im.size == (128, 128) assert im.mode == "L" + assert_image_equal(im, hopper("L")) + def test_invalid_file(): # Arrange @@ -23,23 +27,14 @@ def test_invalid_file(): # Act / Assert with pytest.raises(SyntaxError): - FitsStubImagePlugin.FITSStubImageFile(invalid_file) - - -def test_load(): - # Arrange - with Image.open(TEST_FILE) as im: - - # Act / Assert: stub cannot load without an implemented handler - with pytest.raises(OSError): - im.load() + FitsImagePlugin.FitsImageFile(invalid_file) 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)) + FitsImagePlugin.FitsImageFile(BytesIO(image_data)) def test_naxis_zero(): @@ -48,16 +43,3 @@ def test_naxis_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: - dummy_fp = None - dummy_filename = "dummy.filename" - - # Act / Assert: stub cannot save without an implemented handler - with pytest.raises(OSError): - im.save(dummy_filename) - with pytest.raises(OSError): - FitsStubImagePlugin._save(im, dummy_fp, dummy_filename) diff --git a/docs/handbook/image-file-formats.rst b/docs/handbook/image-file-formats.rst index bd44f63a3..0a40a0b0b 100644 --- a/docs/handbook/image-file-formats.rst +++ b/docs/handbook/image-file-formats.rst @@ -1064,6 +1064,11 @@ is commonly used in fax applications. The DCX decoder can read files containing When the file is opened, only the first image is read. You can use :py:meth:`~PIL.Image.Image.seek` or :py:mod:`~PIL.ImageSequence` to read other images. +FITS +^^^^ + +Pillow identifies and reads FITS files, commonly used for astronomy. + FLI, FLC ^^^^^^^^ @@ -1354,16 +1359,6 @@ Pillow provides a stub driver for BUFR files. To add read or write support to your application, use :py:func:`PIL.BufrStubImagePlugin.register_handler`. -FITS -^^^^ - -.. versionadded:: 1.1.5 - -Pillow provides a stub driver for FITS files. - -To add read or write support to your application, use -:py:func:`PIL.FitsStubImagePlugin.register_handler`. - GRIB ^^^^ diff --git a/docs/reference/plugins.rst b/docs/reference/plugins.rst index 7094f8784..1ef5d7230 100644 --- a/docs/reference/plugins.rst +++ b/docs/reference/plugins.rst @@ -41,10 +41,10 @@ Plugin reference :undoc-members: :show-inheritance: -:mod:`~PIL.FitsStubImagePlugin` Module +:mod:`~PIL.FitsImagePlugin` Module -------------------------------------- -.. automodule:: PIL.FitsStubImagePlugin +.. automodule:: PIL.FitsImagePlugin :members: :undoc-members: :show-inheritance: diff --git a/src/PIL/FitsStubImagePlugin.py b/src/PIL/FitsImagePlugin.py similarity index 63% rename from src/PIL/FitsStubImagePlugin.py rename to src/PIL/FitsImagePlugin.py index a3a94cf4b..c16300efa 100644 --- a/src/PIL/FitsStubImagePlugin.py +++ b/src/PIL/FitsImagePlugin.py @@ -2,44 +2,28 @@ # The Python Imaging Library # $Id$ # -# FITS stub adapter +# FITS file handling # # Copyright (c) 1998-2003 by Fredrik Lundh # # See the README file for information on usage and redistribution. # +import math + from . import Image, ImageFile -_handler = None - - -def register_handler(handler): - """ - Install application-specific FITS image handler. - - :param handler: Handler object. - """ - global _handler - _handler = handler - - -# -------------------------------------------------------------------- -# Image adapter - def _accept(prefix): return prefix[:6] == b"SIMPLE" -class FITSStubImageFile(ImageFile.StubImageFile): +class FitsImageFile(ImageFile.ImageFile): format = "FITS" format_description = "FITS" def _open(self): - offset = self.fp.tell() - headers = {} while True: header = self.fp.read(80) @@ -75,26 +59,13 @@ class FITSStubImageFile(ImageFile.StubImageFile): self.mode = "F" # rawmode = "F" if number_of_bits == -32 else "F;64F" - self.fp.seek(offset) - - loader = self._load() - if loader: - loader.open(self) - - def _load(self): - return _handler - - -def _save(im, fp, filename): - if _handler is None or not hasattr("_handler", "save"): - raise OSError("FITS save handler not installed") - _handler.save(im, fp, filename) + offset = math.ceil(self.fp.tell() / 2880) * 2880 + self.tile = [("raw", (0, 0) + self.size, offset, (self.mode, 0, -1))] # -------------------------------------------------------------------- # Registry -Image.register_open(FITSStubImageFile.format, FITSStubImageFile, _accept) -Image.register_save(FITSStubImageFile.format, _save) +Image.register_open(FitsImageFile.format, FitsImageFile, _accept) -Image.register_extensions(FITSStubImageFile.format, [".fit", ".fits"]) +Image.register_extensions(FitsImageFile.format, [".fit", ".fits"]) diff --git a/src/PIL/__init__.py b/src/PIL/__init__.py index 45fef241e..6352e088f 100644 --- a/src/PIL/__init__.py +++ b/src/PIL/__init__.py @@ -30,7 +30,7 @@ _plugins = [ "DcxImagePlugin", "DdsImagePlugin", "EpsImagePlugin", - "FitsStubImagePlugin", + "FitsImagePlugin", "FliImagePlugin", "FpxImagePlugin", "FtexImagePlugin",