package nom.tam.fits; /* Copyright: Thomas McGlynn 1997-1998. * This code may be used for any purpose, non-commercial * or commercial so long as this copyright notice is retained * in the source code or included in or referred to in any * derived software. * Many thanks to David Glowacki (U. Wisconsin) for substantial * improvements, enhancements and bug fixes. */ import java.io.*; import java.util.*; import nom.tam.util.*; /** Methods to read/write FITS Header/Data unit (HDU). * This class is generally used either to get access to the Header and Data * objects, or to perform manipulations which affect both the Header and Data. */ public class HDU { /** Create an HDU which points to the given object. This may be either * a primitive array or an 2-d array of objects. * @param x The data to which the HDU points. * @return the appropriate HDU object * @exception FitsException if the HDU could not be created. */ public static BasicHDU create(Object x) throws FitsException { String className = x.getClass().getName(); if (className.equals("[[Ljava.lang.Object;") ) { return new BinaryTableHDU((Object[][] )x); } if (className.startsWith("[")) { return new ImageHDU(x); } throw new FitsException("Expected an array of some sort, not " + className); } public static RandomGroupsHDU createRandomGroups(Object[][] x) throws FitsException { return new RandomGroupsHDU(x); } public static AsciiTableHDU createAsciiTable(Object[][] x) throws FitsException { throw new FitsException("ASCII tables not yet supported"); } /** Create an HDU from the supplied Header object. * @param header the Header for the HDU to be created. * @return the appropriate HDU object * @exception FitsException if the HDU could not be created. */ public static BasicHDU create(Header header) throws FitsException { BasicHDU hdu; if (PrimaryHDU.isHeader(header)) { return new PrimaryHDU(header); } if (ImageHDU.isHeader(header)) { return new ImageHDU(header); } if (BinaryTableHDU.isHeader(header)) { return new BinaryTableHDU(header); } if (AsciiTableHDU.isHeader(header)) { return new AsciiTableHDU(header); } if (RandomGroupsHDU.isHeader(header)) { return new RandomGroupsHDU(header); } if (A3DTableHDU.isHeader(header)) { return new A3DTableHDU(header); } throw new BadHeaderException("Unknown FITS header: Card 1=" + header.getCard(0).trim() + ')'); } /** Read an HDU. * This is the usual method by which the Fits class reads an HDU. * @param stream The data stream the FITS data is to be found on. * @return The HDU that has been read. * @exception FitsException if there was a problem with the data. */ public static BasicHDU readHDU(BufferedDataInputStream stream) throws FitsException, IOException { // Read the FITS header. If we are at EOF, just return null. Header hdr = Header.readHeader(stream); if (hdr == null || !hdr.isValidHeader()) { return null; } // create the appropriate HDU object for this Header BasicHDU hdu; try { hdu = create(hdr); } catch (BadHeaderException e) { try { BasicHDU.skipData(stream, hdr); // Rethrow the original error after skipping data. throw e; } catch (FitsException fe) { // Tell the user we failed to skip data. throw new BadHeaderException( "Could not skip Data section of unknown FITS header (Card 1="+ hdr.getCard(0).trim() + "). Error is: " + fe.getMessage()); } } hdu.readData(stream); return hdu; } /** Skip an HDU * @return true if the HDU was skipped. * @exception FitsException if the data could not be skipped. */ public static boolean skipHDU(BufferedDataInputStream input) throws FitsException, IOException { Header nextHeader = Header.readHeader(input); if (nextHeader == null || !nextHeader.isValidHeader()) { return false; } try { BasicHDU.skipData(input, nextHeader); } catch (IOException e) { throw new FitsException("Error skipping data section:" + e.getMessage()); } return true; } }