Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package nom.tam.fits.header;
import java.util.logging.Logger;
/*
* #%L
* nom.tam FITS library
* %%
* Copyright (C) 1996 - 2024 nom-tam-fits
* %%
* This is free and unencumbered software released into the public domain.
*
* Anyone is free to copy, modify, publish, use, compile, sell, or
* distribute this software, either in source code form or as a compiled
* binary, for any purpose, commercial or non-commercial, and by any
* means.
*
* In jurisdictions that recognize copyright laws, the author or authors
* of this software dedicate any and all copyright interest in the
* software to the public domain. We make this dedication for the benefit
* of the public at large and to the detriment of our heirs and
* successors. We intend this dedication to be an overt act of
* relinquishment in perpetuity of all present and future rights to this
* software under copyright law.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
* #L%
*/
import nom.tam.fits.FitsException;
import nom.tam.fits.FitsFactory;
import nom.tam.fits.Header;
import nom.tam.fits.HeaderCard;
import nom.tam.util.type.ElementType;
/**
* Standard BITPIX values and associated functions. Since the FITS BITPIX keyword has only a handful of legal values, an
* enum provides ideal type-safe representation. It also allows to interface the value for the type of data
* it represents in a natural way.
*
* @author Attila Kovacs
*
* @since 1.16
*/
public enum Bitpix {
/** For FITS data stored as bytes */
BYTE(Byte.TYPE, ElementType.BYTE, "bytes"),
/** For FITS data stored as 16-bit integers */
SHORT(Short.TYPE, ElementType.SHORT, "16-bit integers"),
/** For FITS data stored as 32-bit integers */
INTEGER(Integer.TYPE, ElementType.INT, "32-bit integers"),
/** For FITS data stored as 64-bit integers */
LONG(Long.TYPE, ElementType.LONG, "64-bit integers"),
/** For FITS data stored as 32-bit single-precision floating point values */
FLOAT(Float.TYPE, ElementType.FLOAT, "32-bit floating point"),
/** For FITS data stored as 64-bit double-precision floating point values */
DOUBLE(Double.TYPE, ElementType.DOUBLE, "64-bit floating point");
private static final Logger LOG = Logger.getLogger("nom.tam.fits.HeaderCardParser");
private static final int BITS_TO_BYTES_SHIFT = 3;
/** BITPIX value for byte type data */
public static final int VALUE_FOR_BYTE = 8;
/** BITPIX value for short type data */
public static final int VALUE_FOR_SHORT = 16;
/** BITPIX value for int type data */
public static final int VALUE_FOR_INT = 32;
/** BITPIX value for long type data */
public static final int VALUE_FOR_LONG = 64;
/** BITPIX value for float type data */
public static final int VALUE_FOR_FLOAT = -32;
/** BITPIX value for double type data */
public static final int VALUE_FOR_DOUBLE = -64;
/** the number subclass represented this BITPIX instance */
private Class extends Number> numberType;
/** the library's element type */
private ElementType> elementType;
/** a concise description of the data type represented */
private String description;
/**
* Constructor for a standard BITPIX instance.
*
* @param numberType the Number subclass
* @param elementType the class of data element
* @param desc a concise description of the data type
*/
Bitpix(Class extends Number> numberType, ElementType> elementType, String desc) {
this.numberType = numberType;
this.elementType = elementType;
description = desc;
}
/**
* Returns the FITS element type corresponding to this bitpix value
*
* @return the FITS element type that corresponds to this bitpix value.
*/
public final ElementType> getElementType() {
return elementType;
}
/**
* Returns the sublass of {@link Number} corresponding for this BITPIX value.
*
* @return the number class for this BITPIX instance.
*
* @see #getPrimitiveType()
* @see Bitpix#forNumberType(Class)
*/
public final Class extends Number> getNumberType() {
return numberType;
}
/**
* Returns the primitive built-in Java number type corresponding for this BITPIX value.
*
* @return the primitive class for this BITPIX instance, such as int.class, or
* double.class.
*
* @see #getNumberType()
* @see Bitpix#forPrimitiveType(Class)
*/
public final Class> getPrimitiveType() {
return elementType.primitiveClass();
}
/**
* Returns the FITS standard BITPIX header value for this instance.
*
* @return the standard FITS BITPIX value, such as 8, 16, 32, 64, -32, or -64.
*
* @see Bitpix#forValue(int)
* @see #getHeaderCard()
*/
public final int getHeaderValue() {
return elementType.bitPix();
}
/**
* Returns the Java letter ID for this BITPIX instance, such as the letter ID used in the Java array representation
* of that class. For example, an int[] array has class I[, so the letter ID is
* I.
*
* @return The Java letter ID for arrays corresponding to this BITPIX instance.
*
* @see Bitpix#forArrayID(char)
*/
public final char getArrayID() {
return elementType.type();
}
/**
* Returns a concise description of the data type represented by this BITPIX instance.
*
* @return a brief description of the corresponding data type.
*/
public final String getDescription() {
return description;
}
/**
* Returns the size of a data element, in bytes, for this BITPIX instance
*
* @return the size of a data element in bytes.
*/
public final int byteSize() {
return Math.abs(getHeaderValue()) >>> BITS_TO_BYTES_SHIFT;
}
/**
* Returns the standard FITS header card for this BITPIX instance.
*
* @return the standard FITS header card with the BITPIX keyword and the corresponding value for this instance.
*
* @see #getHeaderValue()
*/
public final HeaderCard getHeaderCard() {
return HeaderCard.create(Standard.BITPIX, getHeaderValue());
}
/**
* Returns the standard BITPIX object for a primitive type.
*
* @param dataType the primitive class, such as int.class.
*
* @return the standard BITPIX associated to the number type
*
* @throws FitsException if the class is not a primitive class, or if its not one that has a corresponding BITPIX
* value (e.g.
* boolean.class).
*
* @see Bitpix#forNumberType(Class)
* @see #getPrimitiveType()
*/
public static Bitpix forPrimitiveType(Class> dataType) throws FitsException {
if (dataType == byte.class) {
return BYTE;
}
if (dataType == short.class) {
return SHORT;
}
if (dataType == int.class) {
return INTEGER;
}
if (dataType == long.class) {
return LONG;
}
if (dataType == float.class) {
return FLOAT;
}
if (dataType == double.class) {
return DOUBLE;
}
if (Object.class.isAssignableFrom(dataType)) {
throw new FitsException("No BITPIX for type: " + dataType + " (expected primitive type)");
}
throw new FitsException("No BITPIX for primitive type: " + dataType);
}
/**
* Returns the standard BITPIX object for a number type.
*
* @param dataType the class of number, such as {@link Integer#TYPE}.
*
* @return the standard BITPIX associated to the number type
*
* @throws FitsException if there is no standard BITPIX value corresponding to the number type (e.g.
* {@link java.math.BigDecimal}).
*
* @see Bitpix#forPrimitiveType(Class)
* @see #getNumberType()
*/
public static Bitpix forNumberType(Class extends Number> dataType) throws FitsException {
if (Byte.class.isAssignableFrom(dataType)) {
return BYTE;
}
if (Short.class.isAssignableFrom(dataType)) {
return SHORT;
}
if (Integer.class.isAssignableFrom(dataType)) {
return INTEGER;
}
if (Long.class.isAssignableFrom(dataType)) {
return LONG;
}
if (Float.class.isAssignableFrom(dataType)) {
return FLOAT;
}
if (Double.class.isAssignableFrom(dataType)) {
return DOUBLE;
}
throw new FitsException("No BITPIX for Number type " + dataType);
}
/**
* Returns the standard BITPIX object based on the value assigned to the BITPIX keyword in the header
*
* @param h the FITS header
*
* @return the standard BITPIX enum that matches the header description, or is inferred from an
* invalid header description (provided {@link FitsFactory#setAllowHeaderRepairs(boolean)}
* is enabled).
*
* @throws FitsException if the header does not contain a BITPIX value or it is invalid and cannot or will not be
* repaired.
*
* @see Bitpix#fromHeader(Header, boolean)
* @see Bitpix#forValue(int)
* @see FitsFactory#setAllowHeaderRepairs(boolean)
*/
public static Bitpix fromHeader(Header h) throws FitsException {
return forValue(h.getIntValue(Standard.BITPIX, 0));
}
/**
* Returns the standard BITPIX object based on the value assigned to the BITPIX keyword in the header
*
* @param h the FITS header
* @param allowRepair if we can try repair non-standard (invalid) BITPIX values.
*
* @return the standard BITPIX enum that matches the header description, or is inferred from an
* invalid header description.
*
* @throws FitsException if the header does not contain a BITPIX value or it is invalid and cannot or will not be
* repaired.
*
* @see Bitpix#fromHeader(Header)
* @see Bitpix#forValue(int, boolean)
*/
public static Bitpix fromHeader(Header h, boolean allowRepair) throws FitsException {
return forValue(h.getIntValue(Standard.BITPIX, 0), allowRepair);
}
/**
* Returns the standard BITPIX enum value for a given integer value, such as 8, 16, 32, 64, -32, or -64. If the
* value is not one of the standard values, then depending on whether header repairs are enabled either an exception
* is thrown, or else the value the value is 'repaired' and a loh entry is made to the logger of {@link Header}.
*
* @param ival The integer value of BITPIX in the FITS header.
*
* @return The standard value as a Java object.
*
* @throws FitsException if the value was invalid or irreparable.
*
* @see Bitpix#forValue(int, boolean)
* @see FitsFactory#setAllowHeaderRepairs(boolean)
* @see #getHeaderValue()
*/
public static Bitpix forValue(int ival) throws FitsException {
try {
return forValue(ival, FitsFactory.isAllowHeaderRepairs());
} catch (FitsException e) {
throw new FitsException(e.getMessage() + "\n\n" + " --> Try FitsFactory.setAllowHeaderRepairs(true).\n");
}
}
/**
* Returns the standard BITPIX enum value for a given integer value, such as 8, 16, 32, 64, -32, or -64. If the
* value is not one of the standard values, then depending on whether repairs are enabled either an exception is
* thrown, or else the value the value is 'repaired' and a loh entry is made to the logger of {@link Header}.
*
* @param ival The integer value of BITPIX in the FITS header.
* @param allowRepair Whether we can fix up invalid values to make them valid.
*
* @return The standard value as a Java object.
*
* @throws FitsException if the value was invalid or irreparable.
*
* @see Bitpix#forValue(int)
* @see #getHeaderValue()
*/
public static Bitpix forValue(int ival, boolean allowRepair) throws FitsException {
if (ival == 0) {
throw new FitsException("Invalid BITPIX value:" + ival);
}
// Normally BITPIX must be one one of the supported values. Unfortunately, some
// commercial cameras fill illegal values, such as 20.
// We can 'repair' them by rounding up to the next valid value, so 20 repairs to 32, and
// maxing at +/- 64, so for example -80 repairs to -64.
if (allowRepair) {
int fixed = 0;
if (ival < 0) {
fixed = ival < VALUE_FOR_FLOAT ? VALUE_FOR_DOUBLE : VALUE_FOR_FLOAT;
} else if (ival < VALUE_FOR_BYTE) {
fixed = VALUE_FOR_BYTE;
} else if (ival > VALUE_FOR_LONG) {
fixed = VALUE_FOR_LONG;
} else if (ival > Integer.highestOneBit(ival)) {
fixed = (Integer.highestOneBit(ival) << 1);
}
if (fixed != 0) {
LOG.warning("Repaired invalid BITPIX value:" + ival + " --> " + fixed);
ival = fixed;
}
}
switch (ival) {
case VALUE_FOR_BYTE:
return BYTE;
case VALUE_FOR_SHORT:
return SHORT;
case VALUE_FOR_INT:
return INTEGER;
case VALUE_FOR_LONG:
return LONG;
case VALUE_FOR_FLOAT:
return FLOAT;
case VALUE_FOR_DOUBLE:
return DOUBLE;
default:
throw new FitsException("Invalid BITPIX value:" + ival);
}
}
/**
* Returns the standard BITPIX object for the given Java array ID. The array ID is the same letter code as Java uses
* for identifying ptrimitive array types. For example a Java array of long[][] has a class name of
* J[[, so so the array ID for long arrays is J.
*
* @param id The Java letter ID for arrays of the underlying primitive type. E.g. J for
* long.
*
* @return The standard BITPIX enum corresponding to the data type.
*
* @throws FitsException if the data type is unknown or does not have a BITPIX ewquivalent.
*/
public static Bitpix forArrayID(char id) throws FitsException {
switch (id) {
case 'B':
return BYTE;
case 'S':
return SHORT;
case 'I':
return INTEGER;
case 'J':
return LONG;
case 'F':
return FLOAT;
case 'D':
return DOUBLE;
default:
throw new FitsException("Invalid BITPIX data ID: '" + id + "'");
}
}
}