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