    001/*****************************************************************************
    002 * Copyright by The HDF Group.                                               *
    003 * Copyright by the Board of Trustees of the University of Illinois.         *
    004 * All rights reserved.                                                      *
    005 *                                                                           *
    006 * This file is part of the HDF Java Products distribution.                  *
    007 * The full copyright notice, including terms governing use, modification,   *
    008 * and redistribution, is contained in the files COPYING and Copyright.html. *
    009 * COPYING can be found at the root of the source code distribution tree.    *
    010 * Or, see https://support.hdfgroup.org/products/licenses.html               *
    011 * If you do not have access to either file, you may request a copy from     *
    012 * help@hdfgroup.org.                                                        *
    013 ****************************************************************************/
    014
    015package hdf.object.fits;
    016
    017import java.util.List;
    018
    019import hdf.object.Datatype;
    020import nom.tam.fits.BasicHDU;
    021
    022/**
    023 * Datatype encapsulates information of a datatype.
    024 * Information includes the class, size, endian of a datatype.
    025 * <p>
    026 * @version 1.1 9/4/2007
    027 * @author Peter X. Cao
    028 */
    029public class FitsDatatype extends Datatype
    030{
    031    private static final long serialVersionUID = 6545936196104493765L;
    032    private long nativeType;
    033
    034    /**
    035     * Create an Datatype with specified class, size, byte order and sign.
    036     * The following list a few example of how to create a Datatype.
    037     * <OL>
    038     * <LI>to create unsigned native integer<br>
    039     * FitsDatatype type = new H5Dataype(Datatype.CLASS_INTEGER, Datatype.NATIVE, Datatype.NATIVE, Datatype.SIGN_NONE);
    040     * <LI>to create 16-bit signed integer with big endian<br>
    041     * FitsDatatype type = new H5Dataype(Datatype.CLASS_INTEGER, 2, Datatype.ORDER_BE, Datatype.NATIVE);
    042     * <LI>to create native float<br>
    043     * FitsDatatype type = new H5Dataype(Datatype.CLASS_FLOAT, Datatype.NATIVE, Datatype.NATIVE, Datatype.NATIVE);
    044     * <LI>to create 64-bit double<br>
    045     * FitsDatatype type = new H5Dataype(Datatype.CLASS_FLOAT, 8, Datatype.NATIVE, Datatype.NATIVE);
    046     * </OL>
    047     *
    048     * @param tclass the class of the datatype.
    049     * @param tsize the size of the datatype in bytes.
    050     * @param torder the order of the datatype.
    051     * @param tsign the sign of the datatype.
    052     *
    053* @throws Exception
    054     *            if there is an error
    055     */
    056    public FitsDatatype(int tclass, int tsize, int torder, int tsign) throws Exception {
    057        super(tclass, tsize, torder, tsign);
    058        datatypeDescription = getDescription();
    059    }
    060
    061    /**
    062     * Create a Datatype with a given fits native datatype.
    063     *
    064     * @param theType the fits native datatype.
    065     *
    066* @throws Exception
    067     *            if there is an error
    068     */
    069    public FitsDatatype(long theType) throws Exception {
    070        super(null, -1);
    071        nativeType = theType;
    072        fromNative(0);
    073        datatypeDescription = getDescription();
    074    }
    075
    076    /*
    077     * (non-Javadoc)
    078     * @see hdf.object.DataFormat#hasAttribute()
    079     */
    080    @Override
    081    public boolean hasAttribute () { return false; }
    082
    083    /**
    084     * Allocate an one-dimensional array of byte, short, int, long, float, double,
    085     * or String to store data retrieved from an fits file based on the given
    086     * fits datatype and dimension sizes.
    087     *
    088     * @param dtype the fits datatype.
    089     * @param size the total size of the array.
    090     * @return the array object if successful and null otherwise.
    091     */
    092    public static Object allocateArray(long dtype, int size) throws OutOfMemoryError
    093    {
    094        Object data = null;
    095
    096        if (size <= 0 ) {
    097            return null;
    098        }
    099
    100        switch ((int)dtype) {
    101            case BasicHDU.BITPIX_BYTE:
    102                data = new byte[size];
    103                break;
    104            case BasicHDU.BITPIX_SHORT:
    105                data = new short[size];
    106                break;
    107            case BasicHDU.BITPIX_INT:
    108                data = new int[size];
    109                break;
    110            case BasicHDU.BITPIX_LONG:
    111                data = new long[size];
    112                break;
    113            case BasicHDU.BITPIX_FLOAT:
    114                data = new float[size];
    115                break;
    116            case BasicHDU.BITPIX_DOUBLE:
    117                data = new double[size];
    118                break;
    119            default:
    120                break;
    121        }
    122
    123        return data;
    124    }
    125
    126    /**
    127     * Translate fits datatype identifier into FitsDatatype.
    128     */
    129    public void fromNative() {
    130        fromNative(nativeType);
    131    }
    132
    133    /**
    134     * Translate fits datatype identifier into FitsDatatype.
    135     *
    136     * @param dtype the fits native datatype.
    137     */
    138    @Override
    139    public void fromNative(long dtype)
    140    {
    141        switch ((int)dtype) {
    142            case BasicHDU.BITPIX_BYTE:
    143                datatypeClass = CLASS_INTEGER;
    144                datatypeSize = 1;
    145                break;
    146            case BasicHDU.BITPIX_SHORT:
    147                datatypeClass = CLASS_INTEGER;
    148                datatypeSize = 2;
    149                break;
    150            case BasicHDU.BITPIX_INT:
    151                datatypeClass = CLASS_INTEGER;
    152                datatypeSize = 4;
    153                break;
    154            case BasicHDU.BITPIX_LONG:
    155                datatypeClass = CLASS_INTEGER;
    156                datatypeSize = 8;
    157                break;
    158            case BasicHDU.BITPIX_FLOAT:
    159                datatypeClass = CLASS_FLOAT;
    160                datatypeSize = 4;
    161                break;
    162            case BasicHDU.BITPIX_DOUBLE:
    163                datatypeClass = CLASS_FLOAT;
    164                datatypeSize = 8;
    165                break;
    166            default:
    167                break;
    168        }
    169    }
    170
    171    // implementing Datatype
    172    @Override
    173    public String getDescription() {
    174        if (datatypeDescription != null)
    175            return datatypeDescription;
    176
    177        String description = null;
    178
    179        switch ((int)nativeType) {
    180            case BasicHDU.BITPIX_BYTE:
    181                description = "8-bit integer";
    182                break;
    183            case BasicHDU.BITPIX_SHORT:
    184                description = "16-bit integer";
    185                break;
    186            case BasicHDU.BITPIX_INT:
    187                description = "32-bit integer";
    188                break;
    189            case BasicHDU.BITPIX_LONG:
    190                description = "64-bit integer";
    191                break;
    192            case BasicHDU.BITPIX_FLOAT:
    193                description = "32-bit float";
    194                break;
    195            case BasicHDU.BITPIX_DOUBLE:
    196                description = "64-bit float";
    197                break;
    198            default:
    199                if (this.isString()) {
    200                    description = "String";
    201                }
    202                else if (this.isChar()) {
    203                    description = "Char";
    204                }
    205                else if (this.isInteger()) {
    206                    description = "Integer";
    207                }
    208                else if (this.isFloat()) {
    209                    description = "Float";
    210                }
    211                else {
    212                    description = "Unknown data type.";
    213                }
    214                break;
    215        }
    216
    217        return description;
    218    }
    219
    220    // implementing Datatype
    221    @Override
    222    public boolean isText() {
    223        return false;
    224    }
    225
    226    // implementing Datatype
    227    @Override
    228    public boolean isUnsigned() {
    229        return false;
    230    }
    231
    232    // implementing Datatype
    233    @Override
    234    public long createNative() {
    235        if (datatypeClass == CLASS_INTEGER) {
    236            if (datatypeSize == 1) {
    237                nativeType = BasicHDU.BITPIX_BYTE;
    238            }
    239            else if (datatypeSize == 2) {
    240                nativeType = BasicHDU.BITPIX_SHORT;
    241            }
    242            else if (datatypeSize == 4) {
    243                nativeType = BasicHDU.BITPIX_INT;
    244            }
    245            else if (datatypeSize == 8) {
    246                nativeType = BasicHDU.BITPIX_LONG;
    247            }
    248        }
    249        else if (datatypeClass == CLASS_FLOAT) {
    250            if (datatypeSize == 4) {
    251                nativeType = BasicHDU.BITPIX_FLOAT;
    252            }
    253            else if (datatypeSize == 8) {
    254                nativeType = BasicHDU.BITPIX_DOUBLE;
    255            }
    256        }
    257
    258        return nativeType;
    259    }
    260
    261    /*
    262     * (non-Javadoc)
    263     * @see hdf.object.Datatype#close(int)
    264     */
    265    @Override
    266    public void close(long id) {
    267        // Nothing to implement
    268    }
    269
    270    // Implementing DataFormat
    271    @SuppressWarnings("rawtypes")
    272    public List getMetadata(int... attrPropList) throws Exception {
    273        throw new UnsupportedOperationException("getMetadata(int... attrPropList) is not supported");
    274    }
    275}