WCSLIB 4.20
fitshdr.h
Go to the documentation of this file.
1 /*============================================================================
2 
3  WCSLIB 4.20 - an implementation of the FITS WCS standard.
4  Copyright (C) 1995-2013, Mark Calabretta
5 
6  This file is part of WCSLIB.
7 
8  WCSLIB is free software: you can redistribute it and/or modify it under the
9  terms of the GNU Lesser General Public License as published by the Free
10  Software Foundation, either version 3 of the License, or (at your option)
11  any later version.
12 
13  WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY
14  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
16  more details.
17 
18  You should have received a copy of the GNU Lesser General Public License
19  along with WCSLIB. If not, see http://www.gnu.org/licenses.
20 
21  Direct correspondence concerning WCSLIB to mark@calabretta.id.au
22 
23  Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
24  http://www.atnf.csiro.au/people/Mark.Calabretta
25  $Id: fitshdr_8h_source.html,v 1.1 2014/02/12 21:11:36 irby Exp $
26 *=============================================================================
27 *
28 * The Flexible Image Transport System (FITS), a data format widely used in
29 * astronomy for data interchange and archive, is described in
30 *
31 * "Definition of the Flexible Image Transport System (FITS), version 3.0",
32 * Pence, W.D., Chiappetti, L., Page, C.G., Shaw, R.A., & Stobie, E. 2010,
33 * A&A, 524, A42 - http://dx.doi.org/10.1051/0004-6361/201015362
34 *
35 * See also http://fits.gsfc.nasa.gov
36 *
37 * Refer to the README file provided with WCSLIB for an overview of the
38 * library.
39 *
40 *
41 * Summary of the fitshdr routines
42 * -------------------------------
43 * fitshdr() is a generic FITS header parser provided to handle keyrecords that
44 * are ignored by the WCS header parsers, wcspih() and wcsbth(). Typically the
45 * latter may be set to remove WCS keyrecords from a header leaving fitshdr()
46 * to handle the remainder.
47 *
48 *
49 * fitshdr() - FITS header parser routine
50 * --------------------------------------
51 * fitshdr() parses a character array containing a FITS header, extracting
52 * all keywords and their values into an array of fitskey structs.
53 *
54 * Given:
55 * header const char []
56 * Character array containing the (entire) FITS header,
57 * for example, as might be obtained conveniently via the
58 * CFITSIO routine fits_hdr2str().
59 *
60 * Each header "keyrecord" (formerly "card image")
61 * consists of exactly 80 7-bit ASCII printing characters
62 * in the range 0x20 to 0x7e (which excludes NUL, BS,
63 * TAB, LF, FF and CR) especially noting that the
64 * keyrecords are NOT null-terminated.
65 *
66 * nkeyrec int Number of keyrecords in header[].
67 *
68 * nkeyids int Number of entries in keyids[].
69 *
70 * Given and returned:
71 * keyids struct fitskeyid []
72 * While all keywords are extracted from the header,
73 * keyids[] provides a convienient way of indexing them.
74 * The fitskeyid struct contains three members;
75 * fitskeyid::name must be set by the user while
76 * fitskeyid::count and fitskeyid::name are returned by
77 * fitshdr(). All matched keywords will have their
78 * fitskey::keyno member negated.
79 *
80 * Returned:
81 * nreject int* Number of header keyrecords rejected for syntax
82 * errors.
83 *
84 * keys struct fitskey**
85 * Pointer to an array of nkeyrec fitskey structs
86 * containing all keywords and keyvalues extracted from
87 * the header.
88 *
89 * Memory for the array is allocated by fitshdr() and
90 * this must be freed by the user by invoking free() on
91 * the array.
92 *
93 * Function return value:
94 * int Status return value:
95 * 0: Success.
96 * 1: Null fitskey pointer passed.
97 * 2: Memory allocation failed.
98 * 3: Fatal error returned by Flex parser.
99 *
100 * Notes:
101 * 1: Keyword parsing is done in accordance with the syntax defined by
102 * NOST 100-2.0, noting the following points in particular:
103 *
104 * a: Sect. 5.1.2.1 specifies that keywords be left-justified in columns
105 * 1-8, blank-filled with no embedded spaces, composed only of the
106 * ASCII characters ABCDEFGHJKLMNOPQRSTUVWXYZ0123456789-_
107 *
108 * fitshdr() accepts any characters in columns 1-8 but flags keywords
109 * that do not conform to standard syntax.
110 *
111 * b: Sect. 5.1.2.2 defines the "value indicator" as the characters "= "
112 * occurring in columns 9 and 10. If these are absent then the
113 * keyword has no value and columns 9-80 may contain any ASCII text
114 * (but see note 2 for CONTINUE keyrecords). This is copied to the
115 * comment member of the fitskey struct.
116 *
117 * c: Sect. 5.1.2.3 states that a keyword may have a null (undefined)
118 * value if the value/comment field, columns 11-80, consists entirely
119 * of spaces, possibly followed by a comment.
120 *
121 * d: Sect. 5.1.1 states that trailing blanks in a string keyvalue are
122 * not significant and the parser always removes them. A string
123 * containing nothing but blanks will be replaced with a single
124 * blank.
125 *
126 * Sect. 5.2.1 also states that a quote character (') in a string
127 * value is to be represented by two successive quote characters and
128 * the parser removes the repeated quote.
129 *
130 * e: The parser recognizes free-format character (NOST 100-2.0,
131 * Sect. 5.2.1), integer (Sect. 5.2.3), and floating-point values
132 * (Sect. 5.2.4) for all keywords.
133 *
134 * f: Sect. 5.2.3 offers no comment on the size of an integer keyvalue
135 * except indirectly in limiting it to 70 digits. The parser will
136 * translates an integer keyvalue to a 32-bit signed integer if it
137 * lies in the range -2147483648 to +2147483647, otherwise it
138 * interprets it as a 64-bit signed integer if possible, or else a
139 * "very long" integer (see fitskey::type).
140 *
141 * g: END not followed by 77 blanks is not considered to be a legitimate
142 * end keyrecord.
143 *
144 * 2: The parser supports a generalization of the OGIP Long String Keyvalue
145 * Convention (v1.0) whereby strings may be continued onto successive
146 * header keyrecords. A keyrecord contains a segment of a continued
147 * string if and only if
148 *
149 * a: it contains the pseudo-keyword CONTINUE,
150 *
151 * b: columns 9 and 10 are both blank,
152 *
153 * c: columns 11 to 80 contain what would be considered a valid string
154 * keyvalue, including optional keycomment, if column 9 had contained
155 * '=',
156 *
157 * d: the previous keyrecord contained either a valid string keyvalue or
158 * a valid CONTINUE keyrecord.
159 *
160 * If any of these conditions is violated, the keyrecord is considered in
161 * isolation.
162 *
163 * Syntax errors in keycomments in a continued string are treated more
164 * permissively than usual; the '/' delimiter may be omitted provided that
165 * parsing of the string keyvalue is not compromised. However, the
166 * FITSHDR_COMMENT status bit will be set for the keyrecord (see
167 * fitskey::status).
168 *
169 * As for normal strings, trailing blanks in a continued string are not
170 * significant.
171 *
172 * In the OGIP convention "the '&' character is used as the last non-blank
173 * character of the string to indicate that the string is (probably)
174 * continued on the following keyword". This additional syntax is not
175 * required by fitshdr(), but if '&' does occur as the last non-blank
176 * character of a continued string keyvalue then it will be removed, along
177 * with any trailing blanks. However, blanks that occur before the '&'
178 * will be preserved.
179 *
180 *
181 * fitskeyid struct - Keyword indexing
182 * -----------------------------------
183 * fitshdr() uses the fitskeyid struct to return indexing information for
184 * specified keywords. The struct contains three members, the first of which,
185 * fitskeyid::name, must be set by the user with the remainder returned by
186 * fitshdr().
187 *
188 * char name[12]:
189 * (Given) Name of the required keyword. This is to be set by the user;
190 * the '.' character may be used for wildcarding. Trailing blanks will be
191 * replaced with nulls.
192 *
193 * int count:
194 * (Returned) The number of matches found for the keyword.
195 *
196 * int idx[2]:
197 * (Returned) Indices into keys[], the array of fitskey structs returned by
198 * fitshdr(). Note that these are 0-relative array indices, not keyrecord
199 * numbers.
200 *
201 * If the keyword is found in the header the first index will be set to the
202 * array index of its first occurrence, otherwise it will be set to -1.
203 *
204 * If multiples of the keyword are found, the second index will be set to
205 * the array index of its last occurrence, otherwise it will be set to -1.
206 *
207 *
208 * fitskey struct - Keyword/value information
209 * ------------------------------------------
210 * fitshdr() returns an array of fitskey structs, each of which contains the
211 * result of parsing one FITS header keyrecord. All members of the fitskey
212 * struct are returned by fitshdr(), none are given by the user.
213 *
214 * int keyno
215 * (Returned) Keyrecord number (1-relative) in the array passed as input to
216 * fitshdr(). This will be negated if the keyword matched any specified in
217 * the keyids[] index.
218 *
219 * int keyid
220 * (Returned) Index into the first entry in keyids[] with which the
221 * keyrecord matches, else -1.
222 *
223 * int status
224 * (Returned) Status flag bit-vector for the header keyrecord employing the
225 * following bit masks defined as preprocessor macros:
226 *
227 * - FITSHDR_KEYWORD: Illegal keyword syntax.
228 * - FITSHDR_KEYVALUE: Illegal keyvalue syntax.
229 * - FITSHDR_COMMENT: Illegal keycomment syntax.
230 * - FITSHDR_KEYREC: Illegal keyrecord, e.g. an END keyrecord with
231 * trailing text.
232 * - FITSHDR_TRAILER: Keyrecord following a valid END keyrecord.
233 *
234 * The header keyrecord is syntactically correct if no bits are set.
235 *
236 * char keyword[12]
237 * (Returned) Keyword name, null-filled for keywords of less than eight
238 * characters (trailing blanks replaced by nulls).
239 *
240 * Use
241 *
242 = sprintf(dst, "%.8s", keyword)
243 *
244 * to copy it to a character array with null-termination, or
245 *
246 = sprintf(dst, "%8.8s", keyword)
247 *
248 * to blank-fill to eight characters followed by null-termination.
249 *
250 * int type
251 * (Returned) Keyvalue data type:
252 * - 0: No keyvalue.
253 * - 1: Logical, represented as int.
254 * - 2: 32-bit signed integer.
255 * - 3: 64-bit signed integer (see below).
256 * - 4: Very long integer (see below).
257 * - 5: Floating point (stored as double).
258 * - 6: Integer complex (stored as double[2]).
259 * - 7: Floating point complex (stored as double[2]).
260 * - 8: String.
261 * - 8+10*n: Continued string (described below and in fitshdr() note 2).
262 *
263 * A negative type indicates that a syntax error was encountered when
264 * attempting to parse a keyvalue of the particular type.
265 *
266 * Comments on particular data types:
267 * - 64-bit signed integers lie in the range
268 *
269 = (-9223372036854775808 <= int64 < -2147483648) ||
270 = (+2147483647 < int64 <= +9223372036854775807)
271 *
272 * A native 64-bit data type may be defined via preprocessor macro
273 * WCSLIB_INT64 defined in wcsconfig.h, e.g. as 'long long int'; this
274 * will be typedef'd to 'int64' here. If WCSLIB_INT64 is not set, then
275 * int64 is typedef'd to int[3] instead and fitskey::keyvalue is to be
276 * computed as
277 *
278 = ((keyvalue.k[2]) * 1000000000 +
279 = keyvalue.k[1]) * 1000000000 +
280 = keyvalue.k[0]
281 *
282 * and may reported via
283 *
284 = if (keyvalue.k[2]) {
285 = printf("%d%09d%09d", keyvalue.k[2], abs(keyvalue.k[1]),
286 = abs(keyvalue.k[0]));
287 = } else {
288 = printf("%d%09d", keyvalue.k[1], abs(keyvalue.k[0]));
289 = }
290 *
291 * where keyvalue.k[0] and keyvalue.k[1] range from -999999999 to
292 * +999999999.
293 *
294 * - Very long integers, up to 70 decimal digits in length, are encoded
295 * in keyvalue.l as an array of int[8], each of which stores 9 decimal
296 * digits. fitskey::keyvalue is to be computed as
297 *
298 = (((((((keyvalue.l[7]) * 1000000000 +
299 = keyvalue.l[6]) * 1000000000 +
300 = keyvalue.l[5]) * 1000000000 +
301 = keyvalue.l[4]) * 1000000000 +
302 = keyvalue.l[3]) * 1000000000 +
303 = keyvalue.l[2]) * 1000000000 +
304 = keyvalue.l[1]) * 1000000000 +
305 = keyvalue.l[0]
306 *
307 * - Continued strings are not reconstructed, they remain split over
308 * successive fitskey structs in the keys[] array returned by
309 * fitshdr(). fitskey::keyvalue data type, 8 + 10n, indicates the
310 * segment number, n, in the continuation.
311 *
312 * int padding
313 * (An unused variable inserted for alignment purposes only.)
314 *
315 * union keyvalue
316 * (Returned) A union comprised of
317 *
318 * - fitskey::i,
319 * - fitskey::k,
320 * - fitskey::l,
321 * - fitskey::f,
322 * - fitskey::c,
323 * - fitskey::s,
324 *
325 * used by the fitskey struct to contain the value associated with a
326 * keyword.
327 *
328 * int i
329 * (Returned) Logical (fitskey::type == 1) and 32-bit signed integer
330 * (fitskey::type == 2) data types in the fitskey::keyvalue union.
331 *
332 * int64 k
333 * (Returned) 64-bit signed integer (fitskey::type == 3) data type in the
334 * fitskey::keyvalue union.
335 *
336 * int l[8]
337 * (Returned) Very long integer (fitskey::type == 4) data type in the
338 * fitskey::keyvalue union.
339 *
340 * double f
341 * (Returned) Floating point (fitskey::type == 5) data type in the
342 * fitskey::keyvalue union.
343 *
344 * double c[2]
345 * (Returned) Integer and floating point complex (fitskey::type == 6 || 7)
346 * data types in the fitskey::keyvalue union.
347 *
348 * char s[72]
349 * (Returned) Null-terminated string (fitskey::type == 8) data type in the
350 * fitskey::keyvalue union.
351 *
352 * int ulen
353 * (Returned) Where a keycomment contains a units string in the standard
354 * form, e.g. [m/s], the ulen member indicates its length, inclusive of
355 * square brackets. Otherwise ulen is zero.
356 *
357 * char comment[84]
358 * (Returned) Keycomment, i.e. comment associated with the keyword or, for
359 * keyrecords rejected because of syntax errors, the compete keyrecord
360 * itself with null-termination.
361 *
362 * Comments are null-terminated with trailing spaces removed. Leading
363 * spaces are also removed from keycomments (i.e. those immediately
364 * following the '/' character), but not from COMMENT or HISTORY keyrecords
365 * or keyrecords without a value indicator ("= " in columns 9-80).
366 *
367 *
368 * Global variable: const char *fitshdr_errmsg[] - Status return messages
369 * ----------------------------------------------------------------------
370 * Error messages to match the status value returned from each function.
371 *
372 *===========================================================================*/
373 
374 #ifndef WCSLIB_FITSHDR
375 #define WCSLIB_FITSHDR
376 
377 #include "wcsconfig.h"
378 
379 #ifdef __cplusplus
380 extern "C" {
381 #endif
382 
383 #define FITSHDR_KEYWORD 0x01
384 #define FITSHDR_KEYVALUE 0x02
385 #define FITSHDR_COMMENT 0x04
386 #define FITSHDR_KEYREC 0x08
387 #define FITSHDR_CARD 0x08 /* Alias for backwards compatibility. */
388 #define FITSHDR_TRAILER 0x10
389 
390 
391 extern const char *fitshdr_errmsg[];
392 
393 #ifdef WCSLIB_INT64
394  typedef WCSLIB_INT64 int64;
395 #else
396  typedef int int64[3];
397 #endif
398 
399 
400 /* Struct used for indexing the keywords. */
401 struct fitskeyid {
402  char name[12]; /* Keyword name, null-terminated. */
403  int count; /* Number of occurrences of keyword. */
404  int idx[2]; /* Indices into fitskey array. */
405 };
406 
407 /* Size of the fitskeyid struct in int units, used by the Fortran wrappers. */
408 #define KEYIDLEN (sizeof(struct fitskeyid)/sizeof(int))
409 
410 
411 /* Struct used for storing FITS keywords. */
412 struct fitskey {
413  int keyno; /* Header keyrecord sequence number (1-rel).*/
414  int keyid; /* Index into fitskeyid[]. */
415  int status; /* Header keyrecord status bit flags. */
416  char keyword[12]; /* Keyword name, null-filled. */
417  int type; /* Keyvalue type (see above). */
418  int padding; /* (Dummy inserted for alignment purposes.) */
419  union {
420  int i; /* 32-bit integer and logical values. */
421  int64 k; /* 64-bit integer values. */
422  int l[8]; /* Very long signed integer values. */
423  double f; /* Floating point values. */
424  double c[2]; /* Complex values. */
425  char s[72]; /* String values, null-terminated. */
426  } keyvalue; /* Keyvalue. */
427  int ulen; /* Length of units string. */
428  char comment[84]; /* Comment (or keyrecord), null-terminated. */
429 };
430 
431 /* Size of the fitskey struct in int units, used by the Fortran wrappers. */
432 #define KEYLEN (sizeof(struct fitskey)/sizeof(int))
433 
434 
435 int fitshdr(const char header[], int nkeyrec, int nkeyids,
436  struct fitskeyid keyids[], int *nreject, struct fitskey **keys);
437 
438 
439 #ifdef __cplusplus
440 }
441 #endif
442 
443 #endif /* WCSLIB_FITSHDR */