Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Rolled back the current scale of my ambitions for supporting older CF…

…ITSIO versions. Now the earliers version for which all tests pass is 3.09. 3.08 passes except for one test which fails due to a bug in CFITSIO itself. But now versions earlier than 3.28 which do not support the GZIP_COMPRESSED_DATA column will work. This required a few small bug fixes: Most importantly was a fix to updateCompressedData to ensure that the memory allocated for compressed data is a multiple of 2880 bytes.
  • Loading branch information...
commit d8d4b8f4762f475552b1aa06bbd28159193283d0 1 parent 5d7fb31
@embray authored
View
6 README.txt
@@ -22,5 +22,7 @@ compression support. A minimal copy of CFITSIO is included in the PyFITS
source under cextern/cfitsio. Packagers wishing to link with an existing
system CFITSIO remove this directory and modify the setup.cfg as instructed
by the comments in that file. CFITSIO support has been tested for versions
-3.28 through 3.30. Earlier versions *may* work by YMMV. Please send in any
-results of experimentation with other CFITSIO versions.
+3.08 through 3.30. The earliers known fully working version is 3.09. Version
+3.08 mostly works except for a bug in CFITSIO itself when decompressing some
+images with BITPIX=-64. Earlier versions *may* work but YMMV. Please send in
+any results of experimentation with other CFITSIO versions.
View
69 lib/pyfits/hdu/compressed.py
@@ -34,7 +34,6 @@
# CFITSIO version-specific features
if COMPRESSION_SUPPORTED:
CFITSIO_SUPPORTS_GZIPDATA = compression.CFITSIO_VERSION >= 3.28
- CFITSIO_SUPPORTS_BYTEPIX = compression.CFITSIO_VERSION >= 3.08
class CompImageHeader(Header):
@@ -759,29 +758,21 @@ def updateHeaderData(self, image_header,
self._header.set('ZVAL1', DEFAULT_BLOCK_SIZE, 'pixels per block',
after='ZNAME1')
- if CFITSIO_SUPPORTS_BYTEPIX:
- # CFITSIO version prior to 3.08 do not support the BYTEPIX
- # compression parameter, and ZVAL2 for Rice compression should
- # be the NOISEBIT parameter
- self._header.set('ZNAME2', 'BYTEPIX',
- 'bytes per pixel (1, 2, 4, or 8)',
- after='ZVAL1')
-
- if self._header['ZBITPIX'] == 8:
- bytepix = 1
- elif self._header['ZBITPIX'] == 16:
- bytepix = 2
- else:
- bytepix = DEFAULT_BYTE_PIX
+ self._header.set('ZNAME2', 'BYTEPIX',
+ 'bytes per pixel (1, 2, 4, or 8)', after='ZVAL1')
- self._header.set('ZVAL2', bytepix,
- 'bytes per pixel (1, 2, 4, or 8)',
- after='ZNAME2')
- afterCard = 'ZVAL2'
- idx = 3
+ if self._header['ZBITPIX'] == 8:
+ bytepix = 1
+ elif self._header['ZBITPIX'] == 16:
+ bytepix = 2
else:
- afterCard = 'ZVAL1'
- idx = 2
+ bytepix = DEFAULT_BYTE_PIX
+
+ self._header.set('ZVAL2', bytepix,
+ 'bytes per pixel (1, 2, 4, or 8)',
+ after='ZNAME2')
+ afterCard = 'ZVAL2'
+ idx = 3
elif compressionType == 'HCOMPRESS_1':
self._header.set('ZNAME1', 'SCALE', 'HCOMPRESS scale factor',
after=afterCard)
@@ -951,6 +942,7 @@ def compData(self):
# data) from the file, if there is any.
compData = super(BinTableHDU, self).data
if isinstance(compData, np.rec.recarray):
+ del self.data
return compData
else:
# This will actually set self.compData with the pre-allocated space
@@ -1264,6 +1256,11 @@ def updateCompressedData(self):
if dataspan < BLOCK_SIZE:
# We must a full FITS block at a minimum
dataspan = BLOCK_SIZE
+ else:
+ # Still make sure to pad out to a multiple of 2880 byte blocks
+ # otherwise CFITSIO can get read errors when it tries to read
+ # a partial block that goes past the end of the file
+ dataspan += _pad_length(dataspan)
self.compData = np.empty((dataspan,), dtype=np.byte)
self.compData[:tbsize] = 0
@@ -1351,23 +1348,19 @@ def updateHeader(self):
self._header.set('ZVAL1', DEFAULT_BLOCK_SIZE, 'pixels per block',
after='ZNAME1')
- if CFITSIO_SUPPORTS_BYTEPIX:
- # CFITSIO < 3.08 does not support the BYTEPIX parameter for
- # Rice compression
- self._header.set('ZNAME2', 'BYTEPIX',
- 'bytes per pixel (1, 2, 4, or 8)',
- after='ZVAL1')
-
- if self._header['ZBITPIX'] == 8:
- bytepix = 1
- elif self._header['ZBITPIX'] == 16:
- bytepix = 2
- else:
- bytepix = DEFAULT_BYTE_PIX
+ self._header.set('ZNAME2', 'BYTEPIX',
+ 'bytes per pixel (1, 2, 4, or 8)', after='ZVAL1')
- self._header.set('ZVAL2', bytepix,
- 'bytes per pixel (1, 2, 4, or 8)',
- after='ZNAME2')
+ if self._header['ZBITPIX'] == 8:
+ bytepix = 1
+ elif self._header['ZBITPIX'] == 16:
+ bytepix = 2
+ else:
+ bytepix = DEFAULT_BYTE_PIX
+
+ self._header.set('ZVAL2', bytepix,
+ 'bytes per pixel (1, 2, 4, or 8)',
+ after='ZNAME2')
def scale(self, type=None, option='old', bscale=1, bzero=0):
"""
View
15 src/compressionmodule.c
@@ -584,14 +584,8 @@ void configure_compression(fitsfile* fileptr, PyObject* header) {
// Set some more default compression options
Fptr->rice_blocksize = DEFAULT_BLOCK_SIZE;
-#ifdef CFITSIO_SUPPORTS_BYTEPIX
Fptr->rice_bytepix = DEFAULT_BYTE_PIX;
-#endif
-#ifdef CFITSIO_SUPPORTS_QUANTIZE_LEVEL
Fptr->quantize_level = DEFAULT_QUANTIZE_LEVEL;
-#else
- Fptr->rice_nbits = DEFAULT_QUANTIZE_LEVEL;
-#endif
Fptr->hcomp_smooth = DEFAULT_HCOMP_SMOOTH;
Fptr->hcomp_scale = DEFAULT_HCOMP_SCALE;
@@ -610,11 +604,9 @@ void configure_compression(fitsfile* fileptr, PyObject* header) {
if (0 == strcmp(zname, "BLOCKSIZE")) {
get_header_int(header, keyword, &(Fptr->rice_blocksize),
DEFAULT_BLOCK_SIZE);
-#ifdef CFITSIO_SUPPORTS_BYTEPIX
} else if (0 == strcmp(zname, "BYTEPIX")) {
get_header_int(header, keyword, &(Fptr->rice_bytepix),
DEFAULT_BYTE_PIX);
-#endif
}
} else if (Fptr->compress_type == HCOMPRESS_1) {
if (0 == strcmp(zname, "SMOOTH")) {
@@ -792,7 +784,6 @@ PyObject* compression_compress_hdu(PyObject* self, PyObject* args)
indata = (PyArrayObject*) PyObject_GetAttrString(hdu, "data");
- // Test values
fits_write_img(fileptr, datatype, 1, PyArray_SIZE(indata), indata->data,
&status);
if (status != 0) {
@@ -840,6 +831,9 @@ PyObject* compression_compress_hdu(PyObject* self, PyObject* args)
}
Py_XDECREF(indata);
+ // Clear any messages remaining in CFITSIO's error stack
+ fits_clear_errmsg();
+
return retval;
}
@@ -914,6 +908,9 @@ PyObject* compression_decompress_hdu(PyObject* self, PyObject* args)
}
PyMem_Free(znaxis);
+ // Clear any messages remaining in CFITSIO's error stack
+ fits_clear_errmsg();
+
return (PyObject*) outdata;
}
Please sign in to comment.
Something went wrong with that request. Please try again.