1 package nom.tam.fits.header; 2 3 /* 4 * #%L 5 * nom.tam FITS library 6 * %% 7 * Copyright (C) 1996 - 2024 nom-tam-fits 8 * %% 9 * This is free and unencumbered software released into the public domain. 10 * 11 * Anyone is free to copy, modify, publish, use, compile, sell, or 12 * distribute this software, either in source code form or as a compiled 13 * binary, for any purpose, commercial or non-commercial, and by any 14 * means. 15 * 16 * In jurisdictions that recognize copyright laws, the author or authors 17 * of this software dedicate any and all copyright interest in the 18 * software to the public domain. We make this dedication for the benefit 19 * of the public at large and to the detriment of our heirs and 20 * successors. We intend this dedication to be an overt act of 21 * relinquishment in perpetuity of all present and future rights to this 22 * software under copyright law. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 27 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 28 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 29 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 30 * OTHER DEALINGS IN THE SOFTWARE. 31 * #L% 32 */ 33 34 /** 35 * The following keywords are defined by the compression convention for use in the header of the FITS binary table 36 * extension to describe the structure of the compressed image. 37 */ 38 public enum Compression implements IFitsHeader { 39 /** 40 * (required keyword) This keyword must have the logical value T. The value field of this keyword shall be ’T’ to 41 * indicate that the FITS binary table extension contains a compressed BINTABLE, and that logically this extension 42 * should be interpreted as a tile-compressed binary table. 43 */ 44 ZTABLE(VALUE.LOGICAL, "whether this is a compressed table"), 45 46 /** 47 * (required keyword) This keyword must have the logical value T. It indicates that the FITS binary table extension 48 * contains a compressed image and that logically this extension should be interpreted as an image and not as a 49 * table. 50 */ 51 ZIMAGE(VALUE.LOGICAL, "whether this is a compressed image"), 52 53 /** 54 * (required keyword) The value field of this keyword shall contain a character string giving the name of the 55 * algorithm that must be used to decompress the image. Currently, values of GZIP 1 , GZIP 2 , RICE 1 , PLIO 1 , and 56 * HCOMPRESS 1 are reserved, and the corresponding algorithms are described in a later section of this document . 57 * The value RICE ONE is also reserved as an alias for RICE 1 . 58 */ 59 ZCMPTYPE(VALUE.STRING, "compression algorithm"), 60 61 /** 62 * (required keyword) The value field of this keyword shall contain an integer that gives the value of the BITPIX 63 * keyword in the uncompressed FITS image. 64 */ 65 ZBITPIX(VALUE.INTEGER, "original BITPIX value", Standard.BITPIX), 66 67 /** 68 * (required keyword) The value field of this keyword shall contain an integer that gives the value of the NAXIS 69 * keyword in the uncompressed FITS image. 70 */ 71 ZNAXIS(VALUE.INTEGER, "original NAXIS value", Standard.NAXIS), 72 73 /** 74 * (required keywords) The value field of these keywords shall contain a positive integer that gives the value of 75 * the NAXISn keywords in the uncompressed FITS image. 76 */ 77 ZNAXISn(VALUE.INTEGER, "original NAXISn value", Standard.NAXISn), 78 79 /** 80 * (optional keywords) The value of these indexed keywords (where n ranges from 1 to ZNAXIS ) shall contain a 81 * positive integer representing the number of pixels along axis n of the compression tiles. Each tile of pixels is 82 * compressed separately and stored in a row of a variable-length vector column in the binary table. The size of 83 * each image dimension (given by ZNAXISn ) is not required to be an integer multiple of ZTILEn, and if it is not, 84 * then the last tile along that dimension of the image will contain fewer image pixels than the other tiles. If the 85 * ZTILEn keywords are not present then the default ’row by row’ tiling will be assumed such that ZTILE1 = ZNAXIS1 , 86 * and the value of all the other ZTILEn keywords equals 1. The compressed image tiles are stored in the binary 87 * table in t he same order that the first pixel in each tile appears in the FITS image; the tile containing the 88 * first pixel in the image appears in the first row of the table, and the tile containing the last pixel in the 89 * image appears in the last row of the binary table. 90 */ 91 ZTILEn(VALUE.INTEGER, "image tile size along dimension"), 92 93 /** 94 * (optional keywords) These pairs of optional array keywords (where n is an integer index number starting with 1) 95 * supply the name and value, respectively, of any algorithm-specific parameters that are needed to compress o r 96 * uncompress the image. The value of ZVALn may have any valid FITS datatype. The order of the compression 97 * parameters may be significant, and may be defined as part of the description of the specific decompression 98 * algorithm. 99 */ 100 ZNAMEn(VALUE.STRING, "indexed compression parameter name"), 101 102 /** 103 * (optional keywords) These pairs of optional array keywords (where n is an integer index number starting with 1) 104 * supply the name and value, respectively, of any algorithm-specific parameters that are needed to compress o r 105 * uncompress the image. The value of ZVALn may have any valid FITS datatype. The order of the compression 106 * parameters may be significant, and may be defined as part of the description of the specific decompression 107 * algorithm. 108 */ 109 ZVALn(VALUE.ANY, "indexed compression parameter value"), 110 111 /** 112 * (optional keyword) Used to record the name of the image compression algorithm that was used to compress the 113 * optional null pixel data mask. See the “Preserving undefined pixels with lossy compression” section for more 114 * details. 115 */ 116 ZMASKCMP(VALUE.STRING, "mask compression algorithm"), 117 118 /** 119 * The following optional keyword is defined to store a verbatim copy of the the value and comment field of the 120 * corresponding keyword in the original uncompressed FITS image. These keywords can be used to reconstruct an 121 * identical copy of the original FITS file when the image is uncompressed.preserves the original SIMPLE keyword.may 122 * only be used if the original uncompressed image was contained in the primary array of the FITS file. 123 */ 124 ZSIMPLE(VALUE.LOGICAL, "original SIMPLE value", Standard.SIMPLE), 125 126 /** 127 * The following optional keyword is defined to store a verbatim copy of the the value and comment field of the 128 * corresponding keyword in the original uncompressed FITS image. These keywords can be used to reconstruct an 129 * identical copy o f the original FITS file when the image is uncompressed.preserves the original XTENSION 130 * keyword.may only be used if the original uncompressed image was contained in in IMAGE extension. 131 */ 132 ZTENSION(VALUE.STRING, "original XTENSION value", Standard.XTENSION), 133 134 /** 135 * The following optional keyword is defined to store a verbatim copy of the the value and comment field of the 136 * corresponding keyword in the original uncompressed FITS image. These keywords can be used to reconstruct an 137 * identical copy of the original FITS file when the image is uncompressed.preserves the original EXTEND keyword.may 138 * only be used if the original uncompressed image was contained in the primary array of the FITS file. 139 */ 140 ZEXTEND(VALUE.LOGICAL, "original EXTEND value", Standard.EXTEND), 141 142 /** 143 * The following optional keyword is defined to store a verbatim copy of the the value and comment field of the 144 * corresponding keyword in the original uncompressed FITS image. These keywords can be used to reconstruct an 145 * identical copy o f the original FITS file when the image is uncompressed.preserves the original BLOCKED 146 * keyword.may only be used if the original uncompressed image was contained in the primary array of the FITS file, 147 */ 148 @Deprecated 149 ZBLOCKED(VALUE.LOGICAL, "original BLOCKED value", Standard.BLOCKED), 150 151 /** 152 * The following optional keyword is defined to store a verbatim copy of the the value and comment field of the 153 * corresponding keyword in the original uncompressed FITS image. These keywords can be used to reconstruct an 154 * identical copy o f the original FITS file when the image is uncompressed.preserves the original PCOUNT 155 * keyword.may only be used if the original uncompressed image was contained in in IMAGE extension. 156 */ 157 ZPCOUNT(VALUE.INTEGER, "original PCOUNT value", Standard.PCOUNT), 158 159 /** 160 * The following optional keyword is defined to store a verbatim copy of the the value and comment field of the 161 * corresponding keyword in the original uncompressed FITS image. These keywords can be used to reconstruct an 162 * identical copy o f the original FITS file when the image is uncompressed.preserves the original GCOUNT 163 * keyword.may only be used if the original uncompressed image was contained in in IMAGE extension. 164 */ 165 ZGCOUNT(VALUE.INTEGER, "original GCOUNTvalue", Standard.GCOUNT), 166 167 /** 168 * The following optional keyword is defined to store a verbatim copy of the the value and comment field of the 169 * corresponding keyword in the original uncompressed FITS image. These keywords can be used to reconstruct an 170 * identical copy o f the original FITS file when the image is uncompressed.preserves the original CHECKSUM keyword. 171 */ 172 ZHECKSUM(VALUE.STRING, "original CHECKSUM string", Checksum.CHECKSUM), 173 174 /** 175 * The following optional keyword is defined to store a verbatim copy of the the value and comment field of the 176 * corresponding keyword in the original uncompressed FITS image. These keywords can be used to reconstruct an 177 * identical copy o f the original FITS file when the image is uncompressed.preserves the original DATASUM 178 */ 179 ZDATASUM(VALUE.STRING, "original DATASUM value", Checksum.DATASUM), 180 181 /** 182 * (optional keyword) This keyword records the name of the algorithm that was used to quantize floating-point image 183 * pixels into integer values which are then passed to the compression algorithm. 184 */ 185 ZQUANTIZ(VALUE.STRING, "compression quantization algorithm"), 186 187 /** 188 * (optional keyword) The value field of this keyword shall contain an integer that gives the seed value for the 189 * random dithering pattern that was used when quantizing the floating-point pixel values. The value may range from 190 * 1 to 100.00, inclusive. 191 */ 192 ZDITHER0(VALUE.INTEGER, "dither algorithm seed value"), 193 194 /** 195 * When using the quantization method to compress floating-point images, this header is used to store the integer 196 * value that represents undefined pixels (if any) in the scaled integer pixel values. These pixels have an IEEE NaN 197 * value (Not a Number) in the uncompressed floating-point image. The recommended value for ZBLANK is -2147483648 198 * (the largest negative 32-bit integer). 199 */ 200 ZBLANK(VALUE.INTEGER, "original BLANK value"), 201 202 /** 203 * Stores the original heap offset of the uncompressed heap. 204 * 205 * @since 1.19.1 206 */ 207 ZTHEAP(VALUE.INTEGER, "original THEAP value", Standard.THEAP), 208 209 /** 210 * The value field of this keyword shall contain an integer representing the number of rows of data from the 211 * original binary table that are contained in each tile of the compressed table. The number of rows in the last 212 * tile may be less than in the previous tiles. Note that if the entire table is compressed as a single tile, then 213 * the compressed table will only contains a single row, and the ZTILELEN and ZNAXIS2 keywords will have the same 214 * value. 215 */ 216 ZTILELEN(VALUE.INTEGER, "number of rows compressed per tile"), 217 218 /** 219 * The value field of these keywords shall contain the character string values of the corresponding TFORMn keywords 220 * that defines the data type of column n in the original uncompressed FITS table. 221 */ 222 ZFORMn(VALUE.STRING, "compressed column data format", Standard.TFORMn), 223 224 /** 225 * The value field of these keywords shall contain a charac- ter string giving the mnemonic name of the algorithm 226 * that was used to compress column n of the table. The current allowed values are GZIP_1, GZIP_2, and RICE_1, and 227 * the corresponding algorithms 228 */ 229 ZCTYPn(VALUE.STRING, "original CTYPEn"); 230 231 /** 232 * This is the simplest option in which no dithering is performed. The floating-point pixels are simply quantized 233 * using Eq. 1. This option should be assumed if the ZQUANTIZ keyword is not present in the header of the compressed 234 * floating-point image. 235 */ 236 public static final String ZQUANTIZ_NO_DITHER = "NO_DITHER"; 237 238 /** 239 * It should be noted that an image that is quantized using this technique can stil l be unquantized using the 240 * simple linear scaling function given by Eq. 1. The only side effect in this ca se is to introduce slightly more 241 * noise in the image than if the full subtractive dithering algorith m were applied. 242 */ 243 public static final String ZQUANTIZ_SUBTRACTIVE_DITHER_1 = "SUBTRACTIVE_DITHER_1"; 244 245 /** 246 * This dithering algorithm is identical to the SUBTRACTIVE DITHER 1 algorithm described above, ex- cept that any 247 * pixels in the floating-point image that are equa l to 0.0 are represented by the reserved value -2147483647 in 248 * the quantized integer array. When the i mage is subsequently uncompressed and unscaled, these pixels are restored 249 * to their original va lue of 0.0. This dithering option is useful if the zero-valued pixels have special 250 * significance to the da ta analysis software, so that the value of these pixels must not be dithered. 251 */ 252 public static final String ZQUANTIZ_SUBTRACTIVE_DITHER_2 = "SUBTRACTIVE_DITHER_2"; 253 254 /** 255 * Gzip is the compression algorithm used in the free GN U software utility of the same name. It was created by 256 * Jean-loup Gailly and Mark Adler and is based on the DEFLATE algorithm, which is a combination of LZ77 and Huffman 257 * coding. DEFLATE was intended as a replacement for LZW and other patent-encumbered data compression algor ithms 258 * which, at the time, limited the usability of compress and other popular archivers. Furt her information about 259 * this compression technique is readily available on the Internet. The gzip alg orithm has no associated parameters 260 * that need to be specified with the ZNAMEn and ZVALn keywords. 261 */ 262 public static final String ZCMPTYPE_GZIP_1 = "GZIP_1"; 263 264 /** 265 * If ZCMPTYPE = ’GZIP 2’ then the bytes in the array of image pixel values are shuffled in to decreasing order of 266 * significance before being compressed with the gzip algorithm. In other words, bytes are shuffled so that the most 267 * significant byte of every pixel occurs first, in order, followed by the next most significant byte, and so on for 268 * every byte. Since the most significan bytes of the pixel values often have very similar values, grouping them 269 * together in this way often achieves better net compression of the array. This is usually especially effective 270 * when compressing floating-point arrays. 271 */ 272 public static final String ZCMPTYPE_GZIP_2 = "GZIP_2"; 273 274 /** 275 * If ZCMPTYPE = ’RICE 1’ then the Rice algorithm is used to compress and uncompress the image pixels. The Rice 276 * algorithm (Rice, R. F., Yeh, P.-S., and Miller, W. H. 1993, in Proc. of the 9th AIAA Computing in Aerospace 277 * Conf., AIAA-93-4541-CP, American Institute of Aeronautics and Astronautics) is simple and very fast, compressing 278 * or decompressing 10 7 pixels/sec on modern workstations. It requires only enough memory to hold a single block of 279 * 16 or 32 pixels at a time. It codes the pixels in small blocks and so is able to adapt very quickly to changes in 280 * the input image statistics (e.g., Rice has no problem handling cosmic rays, bright stars, saturated pixels, 281 * etc.). 282 */ 283 public static final String ZCMPTYPE_RICE_1 = "RICE_1"; 284 285 /** 286 * If ZCMPTYPE = ’PLIO 1’ then the IRAF PLIO (Pixel List) algorithm is used to compress and uncompress the image 287 * pixels. The PLIO algorithm was developed to store integer-valued image masks in a compressed form. Typical uses 288 * of image masks are to segment images into regions, or to mark bad pixels. Such masks often have large regions of 289 * constant value hence are highly compressible. The compression algorithm used is based on run-length encoding, 290 * with the ability to dynamically follow level changes in the image, allowing a 16-bit encoding to be used 291 * regardless of the image depth. The worst case performance occurs when successive pixels have different values. 292 * Even in this case the encoding will only require one word (16 bits) per mask pixel, provided either the delta 293 * intensity change between pixels is usually less than 12 bits, or the mask represents a zero floored step function 294 * of constant height. The worst case cannot exceed npix*2 words provided the mask depth is 24 bits or less. 295 */ 296 public static final String ZCMPTYPE_PLIO_1 = "PLIO_1"; 297 298 /** 299 * Hcompress is an the image compression package written by Richard L. White for use at the Space Telescope Science 300 * Institute. Hcompress was used to compress the STScI Digitized Sky Survey and has also been used to compress the 301 * preview images in the Hubble Data Archive. Briefly, the method used is: <br> 302 * 1. a wavelet transform called the H-transform (a Haar transform generalized to two dimensions), followed by<br> 303 * 2. quantization that discards noise in the image while retaining the signal on all scales, followed by 10<br> 304 * 3. quadtree coding of the quantized coefficients.<br> 305 * The technique gives very good compression for astronomical images and is relatively fast. The calculations are 306 * carried out using integer arithmetic and a re entirely reversible. Consequently, the program can be used for 307 * either lossy or lossless compression , with no special approach needed for the lossless case (e.g. there is no 308 * need for a file of residuals .) 309 */ 310 public static final String ZCMPTYPE_HCOMPRESS_1 = "HCOMPRESS_1"; 311 312 /** 313 * alternative name for 'RICE 1' 314 */ 315 public static final String ZCMPTYPE_RICE_ONE = "RICE_ONE"; 316 317 /** 318 * compression algorithm that specifies that the data is uncompressed. 319 */ 320 public static final String ZCMPTYPE_NOCOMPRESS = "NOCOMPRESS"; 321 322 /** 323 * Each row of this variable-length column contains the byte st ream that is generated as a result of compressing 324 * the corresponding image tile. The datatype o f the column (as given by the TFORMn keyword) will generally be 325 * either ’1PB’, ’1PI’ , or ’1PJ’ (or the equivalent ’1Q’ format), depending on whether the compression algorithm ge 326 * nerates an output stream of 8-bit bytes, 16-bit integers, or 32-bit integers, respectively. 327 */ 328 public static final String COMPRESSED_DATA_COLUMN = "COMPRESSED_DATA"; 329 330 /** 331 * When using the quantization method to compress floating-poi nt images that is described in Section 4, it 332 * sometimes may not be possible to quantize some o f the tiles (e.g., if the range of pixels values is too large or 333 * if most of the pixels have the sam e value and hence the calculated RMS noise level in the tile is close to 334 * zero). There also may be other rare cases where the nominal compression algorithm can not be applied to certain 335 * tiles. In these cases, one may use an alternate technique in which the raw pixel values are loss lessly 336 * compressed with the GZIP algorithm and the resulting byte stream is stored in the GZIP COMPRESSED DATA column 337 * (with a ’1PB’ or ’1QB’ variable-length array column format). The corresponding COMPRESSED DATA column for these 338 * tiles must contain a null pointer. 339 */ 340 public static final String GZIP_COMPRESSED_DATA_COLUMN = "GZIP_COMPRESSED_DATA"; 341 342 /** 343 * Use of this column is no longer recommended, but it may exist i n older compressed image files that were created 344 * before support for the GZIP COMPRESSED DATA column (describe above) was added to this convention in May 2011. 345 * This variable length co lumn contains the uncompressed pixels for any tiles that cannot be compressed with the 346 * norma l method. 347 */ 348 public static final String UNCOMPRESSED_DATA_COLUMN = "UNCOMPRESSED_DATA"; 349 350 /** 351 * When using the quantization method to compress floating-point images that is described in Section 4, this column 352 * is used to store the integer value that represents undefined pixels (if any) in the scaled integer pixel values. 353 * These pixels have an IEEE NaN value (Not a Number) in the uncompressed floating-point image. The recommended 354 * value for ZBLANK is -2147483648 (the largest negative 32-bit integer). 355 */ 356 public static final String ZBLANK_COLUMN = "ZBLANK"; 357 358 /** 359 * name of the column containing the quant zero value. 360 */ 361 public static final String ZZERO_COLUMN = "ZZERO"; 362 363 /** 364 * name of the column containing the quant scale value. 365 */ 366 public static final String ZSCALE_COLUMN = "ZSCALE"; 367 368 /** 369 * <p> 370 * The null pixels in integer images are flagged by a reserved BLANK value and will be preserved if a lossless 371 * compression algorithm is used. If the image is compressed with a lossy algorithm, however (e.g., H-Compress with 372 * a scale factor greater than 1), then some other technique must be used to identify the null pixels in the image. 373 * </p> 374 * <p> 375 * The recommended method of recording the null pixels when a lossy compression algorithm is used is to create an 376 * integer data mask with the same dimensions as the image tile. Set the null pixels to 1 and all the other pixels 377 * to 0, then compress the mask array using a lossless algorithm such as PLIO or GZIP. Store the compressed byte 378 * stream in a variable-length array column called ’NULL PIXEL MASK’ in the row corresponding to that image tile. 379 * The ZMASKCMP keyword should be used to record the name of the algorithm used to compress the data mask (e.g., 380 * RICE 1). The data mask array pixels will be assumed to have the shortest integer datatype that is supported by 381 * the compression algorithm (i.e., usually 8-bit bytes). 382 * </p> 383 * <p> 384 * When uncompressing the image tile, the software must check if the corresponding compressed data mask exists with 385 * a length greater than 0, and if so, then uncompress the mask and set the corresponding undefined pixels in the 386 * image array to the appropriate value (as given by the BLANK keyword). 387 * </p> 388 */ 389 public static final String NULL_PIXEL_MASK_COLUMN = "NULL_PIXEL_MASK_COLUMN"; 390 391 /** 392 * The number of 8-bit bytes in each original integer pixel value. 393 */ 394 public static final String BYTEPIX = "BYTEPIX"; 395 396 /** 397 * The blocksize parameter for the rise algorithm. 398 */ 399 public static final String BLOCKSIZE = "BLOCKSIZE"; 400 401 /** 402 * The integer scale parameter determines the amount of compression. Scale = 0 or 1 leads to lossless compression, 403 * i.e. the decompressed image has exactly the same pixel values as the original image. If the scale factor is 404 * greater than 1 then the compression is lossy: the decompressed image will not be exactly the same as the 405 * original. 406 */ 407 public static final String SCALE = "SCALE"; 408 409 /** 410 * At high compressions factors the decompressed image begins to appear blocky because of the way information is 411 * discarded. This blockiness is greatly reduced, producing more pleasing images, if the image is smoothed slightly 412 * during decompression. When done properly, the smoothing will not affect any quantitative photometric or 413 * astrometric measurements derived from the compressed image. Of course, the smoothing should never be applied when 414 * the image has been losslessly compressed with a scale factor (defined above) of 0 or 1. 415 */ 416 public static final String SMOOTH = "SMOOTH"; 417 418 private final FitsKey key; 419 420 private final IFitsHeader uncompressedKey; 421 422 Compression(VALUE valueType, String comment) { 423 this(valueType, comment, null); 424 } 425 426 Compression(VALUE valueType, String comment, IFitsHeader uncompressedKey) { 427 key = new FitsKey(name(), IFitsHeader.SOURCE.INTEGRAL, HDU.BINTABLE, valueType, comment); 428 this.uncompressedKey = uncompressedKey; 429 FitsKey.registerStandard(this); 430 } 431 432 @Override 433 public final FitsKey impl() { 434 return key; 435 } 436 437 /** 438 * Returns the equivalent of this comression keyword in the uncompressed HDU. For example, the compression keyword 439 * <code>ZBITPIX</code> that stores the data type of the compressed image will return <code>BITPIX</code>. 440 * 441 * @return the equivalent keyword in the uncompressed HDU 442 */ 443 public IFitsHeader getUncompressedKey() { 444 return uncompressedKey; 445 } 446 447 }