00001 /*============================================================================ 00002 00003 WCSLIB 4.15 - an implementation of the FITS WCS standard. 00004 Copyright (C) 1995-2012, Mark Calabretta 00005 00006 This file is part of WCSLIB. 00007 00008 WCSLIB is free software: you can redistribute it and/or modify it under the 00009 terms of the GNU Lesser General Public License as published by the Free 00010 Software Foundation, either version 3 of the License, or (at your option) 00011 any later version. 00012 00013 WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY 00014 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 00016 more details. 00017 00018 You should have received a copy of the GNU Lesser General Public License 00019 along with WCSLIB. If not, see http://www.gnu.org/licenses. 00020 00021 Direct correspondence concerning WCSLIB to mark@calabretta.id.au 00022 00023 Author: Mark Calabretta, Australia Telescope National Facility, CSIRO. 00024 http://www.atnf.csiro.au/people/Mark.Calabretta 00025 $Id: fitshdr.h,v 4.15 2012/09/26 14:26:05 cal103 Exp $ 00026 *============================================================================= 00027 * 00028 * The Flexible Image Transport System (FITS), a data format widely used in 00029 * astronomy for data interchange and archive, is described in 00030 * 00031 * "Definition of The Flexible Image Transport System (FITS)", 00032 * Hanisch, R.J., Farris, A., Greisen, E.W., et al. 2001, A&A, 376, 359 00033 * 00034 * which formalizes NOST 100-2.0, a document produced by the NASA/Science 00035 * Office of Standards and Technology, see http://fits.gsfc.nasa.gov. 00036 * 00037 * Refer to the README file provided with WCSLIB for an overview of the 00038 * library. 00039 * 00040 * 00041 * Summary of the fitshdr routines 00042 * ------------------------------- 00043 * fitshdr() is a generic FITS header parser provided to handle keyrecords that 00044 * are ignored by the WCS header parsers, wcspih() and wcsbth(). Typically the 00045 * latter may be set to remove WCS keyrecords from a header leaving fitshdr() 00046 * to handle the remainder. 00047 * 00048 * 00049 * fitshdr() - FITS header parser routine 00050 * -------------------------------------- 00051 * fitshdr() parses a character array containing a FITS header, extracting 00052 * all keywords and their values into an array of fitskey structs. 00053 * 00054 * Given: 00055 * header const char [] 00056 * Character array containing the (entire) FITS header, 00057 * for example, as might be obtained conveniently via the 00058 * CFITSIO routine fits_hdr2str(). 00059 * 00060 * Each header "keyrecord" (formerly "card image") 00061 * consists of exactly 80 7-bit ASCII printing characters 00062 * in the range 0x20 to 0x7e (which excludes NUL, BS, 00063 * TAB, LF, FF and CR) especially noting that the 00064 * keyrecords are NOT null-terminated. 00065 * 00066 * nkeyrec int Number of keyrecords in header[]. 00067 * 00068 * nkeyids int Number of entries in keyids[]. 00069 * 00070 * Given and returned: 00071 * keyids struct fitskeyid [] 00072 * While all keywords are extracted from the header, 00073 * keyids[] provides a convienient way of indexing them. 00074 * The fitskeyid struct contains three members; 00075 * fitskeyid::name must be set by the user while 00076 * fitskeyid::count and fitskeyid::name are returned by 00077 * fitshdr(). All matched keywords will have their 00078 * fitskey::keyno member negated. 00079 * 00080 * Returned: 00081 * nreject int* Number of header keyrecords rejected for syntax 00082 * errors. 00083 * 00084 * keys struct fitskey** 00085 * Pointer to an array of nkeyrec fitskey structs 00086 * containing all keywords and keyvalues extracted from 00087 * the header. 00088 * 00089 * Memory for the array is allocated by fitshdr() and 00090 * this must be freed by the user by invoking free() on 00091 * the array. 00092 * 00093 * Function return value: 00094 * int Status return value: 00095 * 0: Success. 00096 * 1: Null fitskey pointer passed. 00097 * 2: Memory allocation failed. 00098 * 3: Fatal error returned by Flex parser. 00099 * 00100 * Notes: 00101 * 1: Keyword parsing is done in accordance with the syntax defined by 00102 * NOST 100-2.0, noting the following points in particular: 00103 * 00104 * a: Sect. 5.1.2.1 specifies that keywords be left-justified in columns 00105 * 1-8, blank-filled with no embedded spaces, composed only of the 00106 * ASCII characters ABCDEFGHJKLMNOPQRSTUVWXYZ0123456789-_ 00107 * 00108 * fitshdr() accepts any characters in columns 1-8 but flags keywords 00109 * that do not conform to standard syntax. 00110 * 00111 * b: Sect. 5.1.2.2 defines the "value indicator" as the characters "= " 00112 * occurring in columns 9 and 10. If these are absent then the 00113 * keyword has no value and columns 9-80 may contain any ASCII text 00114 * (but see note 2 for CONTINUE keyrecords). This is copied to the 00115 * comment member of the fitskey struct. 00116 * 00117 * c: Sect. 5.1.2.3 states that a keyword may have a null (undefined) 00118 * value if the value/comment field, columns 11-80, consists entirely 00119 * of spaces, possibly followed by a comment. 00120 * 00121 * d: Sect. 5.1.1 states that trailing blanks in a string keyvalue are 00122 * not significant and the parser always removes them. A string 00123 * containing nothing but blanks will be replaced with a single 00124 * blank. 00125 * 00126 * Sect. 5.2.1 also states that a quote character (') in a string 00127 * value is to be represented by two successive quote characters and 00128 * the parser removes the repeated quote. 00129 * 00130 * e: The parser recognizes free-format character (NOST 100-2.0, 00131 * Sect. 5.2.1), integer (Sect. 5.2.3), and floating-point values 00132 * (Sect. 5.2.4) for all keywords. 00133 * 00134 * f: Sect. 5.2.3 offers no comment on the size of an integer keyvalue 00135 * except indirectly in limiting it to 70 digits. The parser will 00136 * translates an integer keyvalue to a 32-bit signed integer if it 00137 * lies in the range -2147483648 to +2147483647, otherwise it 00138 * interprets it as a 64-bit signed integer if possible, or else a 00139 * "very long" integer (see fitskey::type). 00140 * 00141 * g: END not followed by 77 blanks is not considered to be a legitimate 00142 * end keyrecord. 00143 * 00144 * 2: The parser supports a generalization of the OGIP Long String Keyvalue 00145 * Convention (v1.0) whereby strings may be continued onto successive 00146 * header keyrecords. A keyrecord contains a segment of a continued 00147 * string if and only if 00148 * 00149 * a: it contains the pseudo-keyword CONTINUE, 00150 * 00151 * b: columns 9 and 10 are both blank, 00152 * 00153 * c: columns 11 to 80 contain what would be considered a valid string 00154 * keyvalue, including optional keycomment, if column 9 had contained 00155 * '=', 00156 * 00157 * d: the previous keyrecord contained either a valid string keyvalue or 00158 * a valid CONTINUE keyrecord. 00159 * 00160 * If any of these conditions is violated, the keyrecord is considered in 00161 * isolation. 00162 * 00163 * Syntax errors in keycomments in a continued string are treated more 00164 * permissively than usual; the '/' delimiter may be omitted provided that 00165 * parsing of the string keyvalue is not compromised. However, the 00166 * FITSHDR_COMMENT status bit will be set for the keyrecord (see 00167 * fitskey::status). 00168 * 00169 * As for normal strings, trailing blanks in a continued string are not 00170 * significant. 00171 * 00172 * In the OGIP convention "the '&' character is used as the last non-blank 00173 * character of the string to indicate that the string is (probably) 00174 * continued on the following keyword". This additional syntax is not 00175 * required by fitshdr(), but if '&' does occur as the last non-blank 00176 * character of a continued string keyvalue then it will be removed, along 00177 * with any trailing blanks. However, blanks that occur before the '&' 00178 * will be preserved. 00179 * 00180 * 00181 * fitskeyid struct - Keyword indexing 00182 * ----------------------------------- 00183 * fitshdr() uses the fitskeyid struct to return indexing information for 00184 * specified keywords. The struct contains three members, the first of which, 00185 * fitskeyid::name, must be set by the user with the remainder returned by 00186 * fitshdr(). 00187 * 00188 * char name[12]: 00189 * (Given) Name of the required keyword. This is to be set by the user; 00190 * the '.' character may be used for wildcarding. Trailing blanks will be 00191 * replaced with nulls. 00192 * 00193 * int count: 00194 * (Returned) The number of matches found for the keyword. 00195 * 00196 * int idx[2]: 00197 * (Returned) Indices into keys[], the array of fitskey structs returned by 00198 * fitshdr(). Note that these are 0-relative array indices, not keyrecord 00199 * numbers. 00200 * 00201 * If the keyword is found in the header the first index will be set to the 00202 * array index of its first occurrence, otherwise it will be set to -1. 00203 * 00204 * If multiples of the keyword are found, the second index will be set to 00205 * the array index of its last occurrence, otherwise it will be set to -1. 00206 * 00207 * 00208 * fitskey struct - Keyword/value information 00209 * ------------------------------------------ 00210 * fitshdr() returns an array of fitskey structs, each of which contains the 00211 * result of parsing one FITS header keyrecord. All members of the fitskey 00212 * struct are returned by fitshdr(), none are given by the user. 00213 * 00214 * int keyno 00215 * (Returned) Keyrecord number (1-relative) in the array passed as input to 00216 * fitshdr(). This will be negated if the keyword matched any specified in 00217 * the keyids[] index. 00218 * 00219 * int keyid 00220 * (Returned) Index into the first entry in keyids[] with which the 00221 * keyrecord matches, else -1. 00222 * 00223 * int status 00224 * (Returned) Status flag bit-vector for the header keyrecord employing the 00225 * following bit masks defined as preprocessor macros: 00226 * 00227 * - FITSHDR_KEYWORD: Illegal keyword syntax. 00228 * - FITSHDR_KEYVALUE: Illegal keyvalue syntax. 00229 * - FITSHDR_COMMENT: Illegal keycomment syntax. 00230 * - FITSHDR_KEYREC: Illegal keyrecord, e.g. an END keyrecord with 00231 * trailing text. 00232 * - FITSHDR_TRAILER: Keyrecord following a valid END keyrecord. 00233 * 00234 * The header keyrecord is syntactically correct if no bits are set. 00235 * 00236 * char keyword[12] 00237 * (Returned) Keyword name, null-filled for keywords of less than eight 00238 * characters (trailing blanks replaced by nulls). 00239 * 00240 * Use 00241 * 00242 = sprintf(dst, "%.8s", keyword) 00243 * 00244 * to copy it to a character array with null-termination, or 00245 * 00246 = sprintf(dst, "%8.8s", keyword) 00247 * 00248 * to blank-fill to eight characters followed by null-termination. 00249 * 00250 * int type 00251 * (Returned) Keyvalue data type: 00252 * - 0: No keyvalue. 00253 * - 1: Logical, represented as int. 00254 * - 2: 32-bit signed integer. 00255 * - 3: 64-bit signed integer (see below). 00256 * - 4: Very long integer (see below). 00257 * - 5: Floating point (stored as double). 00258 * - 6: Integer complex (stored as double[2]). 00259 * - 7: Floating point complex (stored as double[2]). 00260 * - 8: String. 00261 * - 8+10*n: Continued string (described below and in fitshdr() note 2). 00262 * 00263 * A negative type indicates that a syntax error was encountered when 00264 * attempting to parse a keyvalue of the particular type. 00265 * 00266 * Comments on particular data types: 00267 * - 64-bit signed integers lie in the range 00268 * 00269 = (-9223372036854775808 <= int64 < -2147483648) || 00270 = (+2147483647 < int64 <= +9223372036854775807) 00271 * 00272 * A native 64-bit data type may be defined via preprocessor macro 00273 * WCSLIB_INT64 defined in wcsconfig.h, e.g. as 'long long int'; this 00274 * will be typedef'd to 'int64' here. If WCSLIB_INT64 is not set, then 00275 * int64 is typedef'd to int[3] instead and fitskey::keyvalue is to be 00276 * computed as 00277 * 00278 = ((keyvalue.k[2]) * 1000000000 + 00279 = keyvalue.k[1]) * 1000000000 + 00280 = keyvalue.k[0] 00281 * 00282 * and may reported via 00283 * 00284 = if (keyvalue.k[2]) { 00285 = printf("%d%09d%09d", keyvalue.k[2], abs(keyvalue.k[1]), 00286 = abs(keyvalue.k[0])); 00287 = } else { 00288 = printf("%d%09d", keyvalue.k[1], abs(keyvalue.k[0])); 00289 = } 00290 * 00291 * where keyvalue.k[0] and keyvalue.k[1] range from -999999999 to 00292 * +999999999. 00293 * 00294 * - Very long integers, up to 70 decimal digits in length, are encoded 00295 * in keyvalue.l as an array of int[8], each of which stores 9 decimal 00296 * digits. fitskey::keyvalue is to be computed as 00297 * 00298 = (((((((keyvalue.l[7]) * 1000000000 + 00299 = keyvalue.l[6]) * 1000000000 + 00300 = keyvalue.l[5]) * 1000000000 + 00301 = keyvalue.l[4]) * 1000000000 + 00302 = keyvalue.l[3]) * 1000000000 + 00303 = keyvalue.l[2]) * 1000000000 + 00304 = keyvalue.l[1]) * 1000000000 + 00305 = keyvalue.l[0] 00306 * 00307 * - Continued strings are not reconstructed, they remain split over 00308 * successive fitskey structs in the keys[] array returned by 00309 * fitshdr(). fitskey::keyvalue data type, 8 + 10n, indicates the 00310 * segment number, n, in the continuation. 00311 * 00312 * int padding 00313 * (An unused variable inserted for alignment purposes only.) 00314 * 00315 * union keyvalue 00316 * (Returned) A union comprised of 00317 * 00318 * - fitskey::i, 00319 * - fitskey::k, 00320 * - fitskey::l, 00321 * - fitskey::f, 00322 * - fitskey::c, 00323 * - fitskey::s, 00324 * 00325 * used by the fitskey struct to contain the value associated with a 00326 * keyword. 00327 * 00328 * int i 00329 * (Returned) Logical (fitskey::type == 1) and 32-bit signed integer 00330 * (fitskey::type == 2) data types in the fitskey::keyvalue union. 00331 * 00332 * int64 k 00333 * (Returned) 64-bit signed integer (fitskey::type == 3) data type in the 00334 * fitskey::keyvalue union. 00335 * 00336 * int l[8] 00337 * (Returned) Very long integer (fitskey::type == 4) data type in the 00338 * fitskey::keyvalue union. 00339 * 00340 * double f 00341 * (Returned) Floating point (fitskey::type == 5) data type in the 00342 * fitskey::keyvalue union. 00343 * 00344 * double c[2] 00345 * (Returned) Integer and floating point complex (fitskey::type == 6 || 7) 00346 * data types in the fitskey::keyvalue union. 00347 * 00348 * char s[72] 00349 * (Returned) Null-terminated string (fitskey::type == 8) data type in the 00350 * fitskey::keyvalue union. 00351 * 00352 * int ulen 00353 * (Returned) Where a keycomment contains a units string in the standard 00354 * form, e.g. [m/s], the ulen member indicates its length, inclusive of 00355 * square brackets. Otherwise ulen is zero. 00356 * 00357 * char comment[84] 00358 * (Returned) Keycomment, i.e. comment associated with the keyword or, for 00359 * keyrecords rejected because of syntax errors, the compete keyrecord 00360 * itself with null-termination. 00361 * 00362 * Comments are null-terminated with trailing spaces removed. Leading 00363 * spaces are also removed from keycomments (i.e. those immediately 00364 * following the '/' character), but not from COMMENT or HISTORY keyrecords 00365 * or keyrecords without a value indicator ("= " in columns 9-80). 00366 * 00367 * 00368 * Global variable: const char *fitshdr_errmsg[] - Status return messages 00369 * ---------------------------------------------------------------------- 00370 * Error messages to match the status value returned from each function. 00371 * 00372 *===========================================================================*/ 00373 00374 #ifndef WCSLIB_FITSHDR 00375 #define WCSLIB_FITSHDR 00376 00377 #include "wcsconfig.h" 00378 00379 #ifdef __cplusplus 00380 extern "C" { 00381 #endif 00382 00383 #define FITSHDR_KEYWORD 0x01 00384 #define FITSHDR_KEYVALUE 0x02 00385 #define FITSHDR_COMMENT 0x04 00386 #define FITSHDR_KEYREC 0x08 00387 #define FITSHDR_CARD 0x08 /* Alias for backwards compatibility. */ 00388 #define FITSHDR_TRAILER 0x10 00389 00390 00391 extern const char *fitshdr_errmsg[]; 00392 00393 #ifdef WCSLIB_INT64 00394 typedef WCSLIB_INT64 int64; 00395 #else 00396 typedef int int64[3]; 00397 #endif 00398 00399 00400 /* Struct used for indexing the keywords. */ 00401 struct fitskeyid { 00402 char name[12]; /* Keyword name, null-terminated. */ 00403 int count; /* Number of occurrences of keyword. */ 00404 int idx[2]; /* Indices into fitskey array. */ 00405 }; 00406 00407 /* Size of the fitskeyid struct in int units, used by the Fortran wrappers. */ 00408 #define KEYIDLEN (sizeof(struct fitskeyid)/sizeof(int)) 00409 00410 00411 /* Struct used for storing FITS keywords. */ 00412 struct fitskey { 00413 int keyno; /* Header keyrecord sequence number (1-rel).*/ 00414 int keyid; /* Index into fitskeyid[]. */ 00415 int status; /* Header keyrecord status bit flags. */ 00416 char keyword[12]; /* Keyword name, null-filled. */ 00417 int type; /* Keyvalue type (see above). */ 00418 int padding; /* (Dummy inserted for alignment purposes.) */ 00419 union { 00420 int i; /* 32-bit integer and logical values. */ 00421 int64 k; /* 64-bit integer values. */ 00422 int l[8]; /* Very long signed integer values. */ 00423 double f; /* Floating point values. */ 00424 double c[2]; /* Complex values. */ 00425 char s[72]; /* String values, null-terminated. */ 00426 } keyvalue; /* Keyvalue. */ 00427 int ulen; /* Length of units string. */ 00428 char comment[84]; /* Comment (or keyrecord), null-terminated. */ 00429 }; 00430 00431 /* Size of the fitskey struct in int units, used by the Fortran wrappers. */ 00432 #define KEYLEN (sizeof(struct fitskey)/sizeof(int)) 00433 00434 00435 int fitshdr(const char header[], int nkeyrec, int nkeyids, 00436 struct fitskeyid keyids[], int *nreject, struct fitskey **keys); 00437 00438 00439 #ifdef __cplusplus 00440 } 00441 #endif 00442 00443 #endif /* WCSLIB_FITSHDR */