View Javadoc

1   /*
2    $Id: FitsImage.java,v 1.2 2004/01/12 18:45:56 mch Exp $
3   
4    Copyright (c) etc
5    */
6   
7   package org.astrogrid.fits;
8   
9   import java.io.IOException;
10  import java.io.InputStream;
11  import java.util.Hashtable;
12  import org.astrogrid.common.myspace.SourceResolver;
13  import org.astrogrid.log.Log;
14  
15  /***
16   * A set of routines for handling a fits image
17   *
18   * FITS images are binary representations of tables or pixel images, and are
19   * well known in the astronomical community (in 2003!).  They consist of
20   * a number of 'lines' of 80 characters of ASCII keyword/value pairs, then
21   * the binary data itself.
22   *
23   * (Should say more or give reference)
24   *
25   * NB the image might be remote, eg
26   * http or ftp, so we can't deal with instances of File
27   */
28  public class FitsImage
29  {
30     String fileLocation;
31     int dataOffset = -1; //how big is the header. -1 = not loaded yet.
32     Hashtable header = null; //header key/value pairs. null = not loaded yet
33  
34     public FitsImage(String givenLocation) throws IOException
35     {
36        this.fileLocation = givenLocation;
37        getInputStream(); //test it exists
38     }
39  
40     /***
41      * resolves access to the fits image.
42      */
43     public InputStream getInputStream() throws IOException
44     {
45        //test can be found
46        Log.trace("Resolving access to image '"+fileLocation+"'..");
47        return SourceResolver.resolveInputStream(fileLocation);
48  
49     }
50  
51     /***
52      * Loads the header into a set of key/value pairs, and notes the
53      * point at the beginning of the data.
54      */
55     public void loadHeader() throws IOException
56     {
57        Log.trace("Loading image header...");
58        InputStream in = getInputStream();
59        header = new Hashtable();
60  
61        //read a line (80 bytes) at a time until we reach END
62        byte[] block = new byte[80];
63        //for (int j=0;j<block.length;j++) block[j]=5;  //debug to check for nulls
64        String line = "";
65        int lineNum = 0;
66        int totBytesRead = 0;
67  
68        while (!line.toUpperCase().startsWith("END") && !line.toUpperCase().startsWith("HISTORY AIP"))
69        {
70           lineNum++;
71  
72           int bytesRead = in.read(block);
73           int lineBytesRead = bytesRead;
74  
75           //must read the complete 80 bytes - bear in mind we might be
76           //loading off a remote link
77           while ((lineBytesRead <80) && (bytesRead != -1))
78           {
79              bytesRead = in.read(block, lineBytesRead, 80-lineBytesRead);
80              lineBytesRead = lineBytesRead + bytesRead;
81           }
82           totBytesRead = totBytesRead + lineBytesRead;
83  
84           //debug
85           //String t="";
86           //for (int j=0;j<block.length;j++) t=t+"["+block[j]+"] ";
87           //Log.trace(t);
88  
89           //quick check for binary data, just in case there is something
90           //wrong with the header we don't want to have to read the whole
91           // image
92           for (int i=0;i<block.length;i++)
93           {
94              if ( ((block[i] >128) || (block[i] <32)) && (block[i] != 0)   )
95              {
96                 String msg="Binary data encountered before header END in image "+fileLocation+"\n";
97                 msg=msg+new String(block)+"\n";
98                 for (int j=0;j<block.length;j++) msg=msg+"["+block[j]+"] ";
99  
100                throw new IOException(msg);
101             }
102          }
103 
104          line = new String(block);
105          Log.trace(line);
106 
107          int equalsPos = line.indexOf('=');
108          if (equalsPos > -1)
109          {
110             String key = line.substring(0,equalsPos).trim().toUpperCase();
111             String value = line.substring(equalsPos+1).trim();
112 
113             //check for quotes
114             if (value.startsWith("'"))
115             {
116                if ((value.indexOf("'",1) > -1) && (value.indexOf("'") > 1))
117                {
118                   value = value.substring(1,value.indexOf("'",1)-1);
119                }
120             }
121             else
122             {
123                //only check for comment if no quotes - otherwise we may find
124                //slashes in paths, etc
125                int commentPos = value.indexOf('/');
126                if (commentPos>-1)
127                {
128                   value = value.substring(0,commentPos).trim();
129                }
130             }
131 
132             //add to header table
133             header.put(key, value);
134          }
135 
136       } //end while not end
137 
138       if (!line.toUpperCase().startsWith("HISTORY AIP"))
139       {
140          //can only set this if we have actually read the lot
141          dataOffset = totBytesRead;
142       }
143    }
144 
145    /***
146     * Returns the value in the header corresponding to the given key
147     */
148    public String getHeaderValue(String keyword)
149    {
150       return (String) header.get(keyword);
151    }
152 }
153 
154 /*
155  $Log: FitsImage.java,v $
156  Revision 1.2  2004/01/12 18:45:56  mch
157  Switched from obsolete myspace clients to astrogrid ones
158 
159  Revision 1.1.1.1  2003/08/25 18:36:27  mch
160  Reimported to fit It02 source structure
161 
162  Revision 1.1  2003/07/03 18:14:51  mch
163  Fits file handling
164 
165  */