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}