casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
hdu.h
Go to the documentation of this file.
00001 //# hdu.h:
00002 //# Copyright (C) 1993,1994,1995,1996,1997,1999,2000,2002,2003
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //# 
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //# 
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //# 
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //# 
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: hdu.h 21081 2011-05-09 11:36:20Z gervandiepen $
00027 
00028 #ifndef FITS_HDU_H
00029 #define FITS_HDU_H
00030 
00031 # include <casa/aips.h>
00032 # include <fits/FITS/fits.h>
00033 # include <fits/FITS/blockio.h>
00034 # include <casa/BasicSL/String.h>
00035 # include <casa/Arrays/Vector.h>
00036 
00037 //# # include <stdarg.h> // If we ever wan to put varargs support back
00038 
00039 namespace casa { //# NAMESPACE CASA - BEGIN
00040 
00041 class FitsInput;
00042 class FitsOutput;
00043 
00044 //<summary> base class that defines a HDU </summary>
00045 //<synopsis>
00046 // The class HeaderDataUnit contains what is common to all 
00047 // header-data-units, including the collection of keywords.
00048 // From this class a number of FITS header-data-units are 
00049 // derived, each of them with their own rich assortment of 
00050 // functions for accessing and manipulating data of specific types.
00051 //
00052 // The following inheritence hierarchy illustrates the current
00053 // derived classes:
00054 //<srcblock>
00055 //
00056 //                              HeaderDataUnit
00057 //                              /          | 
00058 //                             /           | 
00059 //                   PrimaryArray       ExtensionHeaderDataUnit
00060 //                    /  |  \                              | 
00061 //                   /   |   \                             | 
00062 //        PrimaryGroup   |   ImageExtension                | 
00063 //                       |                                 | 
00064 //                  PrimaryTable                        BinaryTableExtension
00065 //                                                         /
00066 //                                                        /
00067 //                                      AsciiTableExtension
00068 //</srcblock>
00069 //</synopsis>
00070 
00071 class HeaderDataUnit {
00072         friend std::ostream & operator << (std::ostream &, HeaderDataUnit &);
00073     public:
00074         virtual ~HeaderDataUnit();
00075 
00076         Int dims() const                        { return no_dims; }
00077         Int dim(int n) const                    { return dimn[n]; }
00078         OFF_T fitsdatasize() const              { return fits_data_size; }
00079         FITS::ValueType datatype() const        { return data_type; }
00080         Int fitsitemsize() const                { return fits_item_size; }
00081         Int localitemsize() const               { return local_item_size; }
00082         FITS::HDUType hdutype() const           { return hdu_type; }
00083 
00084         // error handling and error codes that can be returned
00085         //<group>
00086         enum HDUErrs { OK, NOMEM, MISSKEY, BADBITPIX, NOAXISN,
00087                 NOPCOUNT, NOGCOUNT, BADPCOUNT, BADGCOUNT, NOGROUPS,
00088                 BADNAXIS, BADREC, BADTYPE, BADRULES, BADSIZE, BADOPER,
00089                 BADCONV,  BADIO };
00090         int err() const { return err_status; }
00091         //</group>
00092 
00093         // skipping one or more HDU's
00094         //<group>
00095         int skip(uInt n);
00096         int skip();
00097         //</group>
00098 
00099         // write the current header
00100         int write_hdr(FitsOutput &);
00101 
00102         // Determines the HDU type and the data type 
00103         // Parameterss: keyword list, hdu type, data type, error handler and 
00104         // error status.
00105         // Returns False if a serious error was detected, otherwise True
00106         static Bool determine_type(FitsKeywordList &, FITS::HDUType &, 
00107                 FITS::ValueType &, FITSErrorHandler, HDUErrs &);
00108 
00109  
00110         // Compute the total size of the data associated with an HDU.  
00111         // The number of dimensions is also determined.  This routine 
00112         // assumes that hdu type has been appropriately set, but it may 
00113         // be changed in the process.  Data type is also determined.
00114         // Returns False if a serious error was detected, otherwise True
00115         static Bool compute_size(FitsKeywordList &, OFF_T &, Int &,
00116                 FITS::HDUType &, FITS::ValueType &, FITSErrorHandler, HDUErrs &);
00117 
00118         // Operations on the HDU's keyword list
00119         //<group>
00120         ConstFitsKeywordList &kwlist(){  return constkwlist_;}
00121         // return the header of the chdu as a vector of String. You can
00122         // force the strings to be length 80 (padded with spaces)
00123         Vector<String> kwlist_str(Bool length80=False);
00124         void firstkw() { kwlist_.first(); }
00125         void lastkw() { kwlist_.last(); }
00126         const FitsKeyword *nextkw() { return kwlist_.next(); }
00127         const FitsKeyword *prevkw() { return kwlist_.prev(); }
00128         const FitsKeyword *currkw() { return kwlist_.curr(); }  
00129         const FitsKeyword *kw(int n) { return kwlist_(n); }
00130         //# 07/21/98 AKH Added const to quite Apogee warnings:
00131         const FitsKeyword *kw(const FITS::ReservedName &n) { 
00132                 return kwlist_(n); }
00133         const FitsKeyword *nextkw(FITS::ReservedName &n) { 
00134                 return kwlist_.next(n); }
00135         const FitsKeyword *kw(FITS::ReservedName &n, int i) { 
00136                 return kwlist_(n,i); }
00137         const FitsKeyword *nextkw(FITS::ReservedName &n, int i) { 
00138                 return kwlist_.next(n,i); }
00139         const FitsKeyword *kw(const char *n) { return kwlist_(n); }
00140         const FitsKeyword *nextkw(const char *n) { return kwlist_.next(n); }
00141         void mk(FITS::ReservedName k, Bool v, const char *c = 0);
00142         void mk(FITS::ReservedName k, const char *v = 0, const char *c = 0);
00143         void mk(FITS::ReservedName k, Int v, const char *c = 0);
00144         void mk(FITS::ReservedName k, double v, const char *c = 0);
00145         void mk(int n, FITS::ReservedName k, Bool v, const char *c = 0);
00146         void mk(int n, FITS::ReservedName k, const char *v, const char *c = 0);
00147         void mk(int n, FITS::ReservedName k, Int v, const char *c = 0);
00148         void mk(int n, FITS::ReservedName k, double v, const char *c = 0);
00149         void mk(const char *n, Bool v, const char *c = 0);
00150         void mk(const char *n, const char *v = 0, const char *c = 0);
00151         void mk(const char *n, Int v, const char *c = 0);
00152         void mk(const char *n, float v, const char *c = 0);
00153         void mk(const char *n, double v, const char *c = 0);
00154         void mk(const char *n, Int r, Int i, const char *c = 0);
00155         void mk(const char *n, float r, float i, const char *c = 0);
00156         void mk(const char *n, double r, double i, const char *c = 0);
00157         void spaces(const char *n = 0, const char *c = 0);
00158         void comment(const char *n = 0, const char *c = 0);
00159         void history(const char *c = 0);
00160         //</group>
00161 
00162         Bool notnull(double x) const { return double_null < x ? True : False; }
00163         Bool notnull(char *s) const { return ! s ? False : (s[0] != '\0' ? True : False); }
00164         Bool notnull(Int l) const { return Int_null < l ? True : False; }
00165 
00166     protected:
00167         //      For input -- ~ should delete the keyword list: kwflag = 1
00168         HeaderDataUnit(FitsInput &, FITS::HDUType, 
00169                        FITSErrorHandler errhandler = FITSError::defaultHandler);
00170         //      For output -- ~ should not delete keyword list: kwflag = 0
00171         // 07/21/98 AKH Clarification: HeaderDataUnit has a copy of the
00172         //              FitsKeywordList, and should delete it.  The kwflag
00173         //              comments above are not important now.
00174         HeaderDataUnit(FitsKeywordList &, FITS::HDUType, 
00175                        FITSErrorHandler errhandler = FITSError::defaultHandler,
00176                        FitsInput * = 0);
00177         // constructor for objects that write only required keyword to fits file.
00178         // the write method to call by these object should be those for the specific
00179         // hdu, such as write_bintbl_hdr().
00180         HeaderDataUnit(FITS::HDUType, 
00181                        FITSErrorHandler errhandler = FITSError::defaultHandler,
00182                        FitsInput * = 0);
00183         // for write required keywords only to use.
00184         bool init_data_unit( FITS::HDUType t );
00185 
00186         FitsKeywordList &kwlist_;
00187         ConstFitsKeywordList constkwlist_;
00188         void posEnd();
00189 
00190         FitsInput *fin;
00191         FITSErrorHandler errfn;
00192         HDUErrs err_status;
00193         void errmsg(HDUErrs, const char *);
00194 
00195         Int no_dims;            // number of dimensions
00196         Int *dimn;              // size of dimension N
00197         //uInt fits_data_size;  // size in bytes of total amount of data
00198         OFF_T fits_data_size;   // size in bytes of total amount of data
00199         FITS::ValueType data_type;      // type of data - derived from BITPIX
00200         Int fits_item_size;     // size in bytes of an item of FITS data
00201         Int local_item_size;    // size in bytes of an item of local data
00202         FITS::HDUType hdu_type; // type of header/data unit
00203         char pad_char;          // char to pad FITS data block
00204 
00205         //<group>
00206         char * assign(FITS::ReservedName);
00207         char * assign(FITS::ReservedName, int);
00208         double asgdbl(FITS::ReservedName, double);
00209         double asgdbl(FITS::ReservedName, int, double);
00210         //</group>
00211         double double_null;
00212         char char_null;
00213         Int Int_null;
00214 
00215     public:
00216         int get_hdr(FITS::HDUType, FitsKeywordList &);
00217         int read_data(char *, Int);
00218         int write_data(FitsOutput &, char *, Int);
00219         OFF_T read_all_data(char *);
00220         int write_all_data(FitsOutput &, char *);
00221 };
00222 
00223 inline std::ostream & operator << (std::ostream &o, HeaderDataUnit &h) {
00224         return o << h.kwlist_; }
00225 inline void HeaderDataUnit::mk(FITS::ReservedName k, Bool v, const char *c) {
00226         posEnd(); kwlist_.mk(k,v,c); }
00227 inline void HeaderDataUnit::mk(FITS::ReservedName k, const char *v, 
00228         const char *c) { posEnd(); kwlist_.mk(k,v,c); }
00229 inline void HeaderDataUnit::mk(FITS::ReservedName k, Int v, const char *c) {
00230         posEnd(); kwlist_.mk(k,v,c); }
00231 inline void HeaderDataUnit::mk(FITS::ReservedName k, double v, const char *c) {
00232         posEnd(); kwlist_.mk(k,v,c); }
00233 inline void HeaderDataUnit::mk(int n, FITS::ReservedName k, Bool v, 
00234         const char *c) { posEnd(); kwlist_.mk(n,k,v,c); }
00235 inline void HeaderDataUnit::mk(int n, FITS::ReservedName k, const char *v, 
00236         const char *c) { posEnd(); kwlist_.mk(n,k,v,c); }
00237 inline void HeaderDataUnit::mk(int n, FITS::ReservedName k, Int v, 
00238         const char *c) { posEnd(); kwlist_.mk(n,k,v,c); }
00239 inline void HeaderDataUnit::mk(int n, FITS::ReservedName k, double v, 
00240         const char *c) { posEnd(); kwlist_.mk(n,k,v,c); }
00241 inline void HeaderDataUnit::mk(const char *n, Bool v, const char *c) {
00242         posEnd(); kwlist_.mk(n,v,c); }
00243 inline void HeaderDataUnit::mk(const char *n, const char *v, const char *c) {
00244         posEnd(); kwlist_.mk(n,v,c); }
00245 inline void HeaderDataUnit::mk(const char *n, Int v, const char *c) {
00246         posEnd(); kwlist_.mk(n,v,c); }
00247 inline void HeaderDataUnit::mk(const char *n, float v, const char *c) {
00248         posEnd(); kwlist_.mk(n,v,c); }
00249 inline void HeaderDataUnit::mk(const char *n, double v, const char *c) {
00250         posEnd(); kwlist_.mk(n,v,c); }
00251 inline void HeaderDataUnit::mk(const char *n, Int r, Int i, const char *c) {
00252         posEnd(); kwlist_.mk(n,r,i,c); }
00253 inline void HeaderDataUnit::mk(const char *n, float r, float i, const char *c) {
00254         posEnd(); kwlist_.mk(n,r,i,c); }
00255 inline void HeaderDataUnit::mk(const char *n, double r, double i, 
00256         const char *c) { posEnd(); kwlist_.mk(n,r,i,c); }
00257 inline void HeaderDataUnit::spaces(const char *n, const char *c) { 
00258         posEnd(); kwlist_.spaces(n,c); }
00259 inline void HeaderDataUnit::comment(const char *n, const char *c) { 
00260         posEnd(); kwlist_.comment(n,c); }
00261 inline void HeaderDataUnit::history(const char *c) { 
00262         posEnd(); kwlist_.history(c); }
00263 
00264 //<summary> templated primary array base class of given type </summary>
00265 //<synopsis>
00266 // A Primary Data Array is represented by the following:
00267 //<srcblock>
00268 //      <Type> data_array [NAXIS1][NAXIS2]...[NAXISN]
00269 //</srcblock>
00270 //
00271 // For a PrimaryArray, dims() gives the number of dimensions
00272 // and dim(i) gives the value of the i-th dimension
00273 //
00274 // WARNING!  Multi-dimensional arrays are stored in FORTRAN order, 
00275 // NOT in C order.  Options on the store, copy, and move functions exist 
00276 // to convert from one order to the other, if that is necessary.
00277 //
00278 // 
00279 // It is important to understand the proper sequence of operations with
00280 // respect to I/O and data access.  For input, the `read()' functions
00281 // allocate an internal buffer of the appropriate size, if not already
00282 // allocated, as well as reading and converting data; a `read()' function
00283 // must be performed prior to accessing the data, i. e. before executing
00284 // any `()', `data()', `copy()', or `move()' function.  For output, the
00285 // `store()' function similarly allocates an internal buffer before
00286 // transfering data, and must be executed prior to any data access or
00287 // `write()' function. Note: If you call any version of store(), do not
00288 // call set_next().
00289 // 
00290 // Writing portions of an array at a time, rather than the entire array,
00291 // is a special case.  The `set_next()' function is provided for this
00292 // purpose. It declares the intention to write out the next N elements and
00293 // must be executed prior to any `data()' function.  It allocates a buffer
00294 // of appropriate size, if not already allocated.  Again, via the `data()'
00295 // functions, one accesses the array as if the entire array were in
00296 // memory.  The `write()' function always writes the number of current
00297 // elements in the internal buffer.  The sequence of operations for each
00298 // portion of the array written would be: 
00299 // <ul>
00300 // <li> `set_next(N)', 
00301 // <li> fill the array using `data(N)' or other `data()' functions
00302 // <li> `write(fout)'.  
00303 // </ul>
00304 // The `set_next()' function must NOT be used with
00305 // `read()' or `store()' functions; unpredictable results will occur.  
00306 //<example>
00307 // The following example illustrates the output cases.
00308 // 
00309 // Suppose we have an image array with 512 rows and 1024 columns
00310 // stored in C-order.  The C declaration would be:
00311 //<srcblock>
00312 //      int source[1024][512];
00313 //</srcblock>
00314 // To write out the entire array:
00315 //<srcblock>
00316 //      FitsOutput fout; // some properly constructed FitsOutput
00317 //      PrimaryArray<FitsLong> pa; // some properly constructed PrimaryArray
00318 //      pa.store(source,CtoF);
00319 //      pa.write(fout);
00320 //</srcblock>
00321 //
00322 // Suppose we wanted to write out the two-dimensional image array a column
00323 // at a time, rather than write out the entire array.  For FITS, dim(0)
00324 // is 512, dim(1) is 1024.  The following code fragment writes one column 
00325 // at a time in the proper FITS Fortran-order.
00326 //
00327 //<srcblock> 
00328 //      for (i = 0; i < dim(1); ++i) {
00329 //              pa.set_next(dim(0));
00330 //              for (j = 0; j < dim(0); ++j)
00331 //                      data(j,i) = source[i][j];
00332 //              pa.write(fout);
00333 //      }
00334 //</srcblock>
00335 //</example>
00336 //
00337 //</synopsis>
00338 
00339 template <class TYPE>
00340 class PrimaryArray : public HeaderDataUnit {
00341     public:
00342         typedef TYPE ElementType;
00343 
00344         // constructor from a FitsInput
00345         PrimaryArray(FitsInput &, FITSErrorHandler= FITSError::defaultHandler);
00346         // constructor from a FitsKeywordList
00347         PrimaryArray(FitsKeywordList &, 
00348                      FITSErrorHandler= FITSError::defaultHandler);
00349         // constructor does not require a FitsKeywordList. call write_priArr_hdr() after construction.
00350         PrimaryArray(FITSErrorHandler= FITSError::defaultHandler);
00351 
00352         // destructor
00353         virtual ~PrimaryArray();
00354 
00355         // General access routines for a primary array
00356         //<group>
00357         double bscale() const           { return bscale_x; }
00358         double bzero() const            { return bzero_x; }
00359         char *bunit() const             { return bunit_x; }
00360         Bool isablank() const           { return isablank_x; }
00361         Int blank() const               { return blank_x; }
00362         char *ctype(int n) const        { return ctype_x[n]; }
00363         double crpix(int n) const       { return crpix_x[n]; }
00364         double crota(int n) const       { return crota_x[n]; }
00365         double crval(int n) const       { return crval_x[n]; }
00366         double cdelt(int n) const       { return cdelt_x[n]; }
00367         double datamax() const          { return datamax_x; }
00368         double datamin() const          { return datamin_x; }
00369         OFF_T nelements() const         { return totsize; }
00370         //</group>
00371 
00372         // The overloaded operator functions `()' all return physical data, i. e.,
00373         // data to which bscale() and bzero() have been applied, via the formula
00374         //<srcblock>
00375         //      physical_data[i] = bscale() * raw_data[i] + bzero().
00376         //</srcblock>
00377         //<group>
00378         double operator () (int, int, int, int, int) const; 
00379         double operator () (int, int, int, int) const; 
00380         double operator () (int, int, int) const; 
00381         double operator () (int, int) const;
00382         double operator () (int) const;
00383         //</group>
00384 
00385         // The various `data()' functions allow one to access and set the raw data 
00386         // itself.  
00387         //<group>
00388         TYPE & data(int, int, int, int, int); 
00389         TYPE & data(int, int, int, int); 
00390         TYPE & data(int, int, int); 
00391         TYPE & data(int, int);
00392         TYPE & data(int);
00393         //</group>
00394 
00395         // The `store()', `move()' and `copy()' functions allow bulk data
00396         // transfer between the internal FITS array and an external data
00397         // storage area.  The external storage must have already been allocated
00398         // and it is assumed that the entire data array is in memory.
00399         // `store()' transfers raw data at `source' into the FITS array; an
00400         // allowable option is CtoF, which specifies to convert the array from
00401         // C-order to Fortran-order.  `move()' is the opposite of `store()'.
00402         // `move()' transfers raw data from the FITS array to `target'; an
00403         // allowable option is FtoC, which specifies to convert the array from
00404         // Fortran-order to C-order.  `copy()' is similar to `move()' except
00405         // that what is copied is physical data and not raw data; the physical
00406         // data can be either double or float. copy() also turns blanks into
00407         // NaN's.
00408         //<group>
00409         int store(const TYPE *source, FITS::FitsArrayOption = FITS::NoOpt);
00410         void copy(double *target, FITS::FitsArrayOption = FITS::NoOpt) const;
00411         void copy(float *target, FITS::FitsArrayOption = FITS::NoOpt) const;
00412         void move(TYPE *target, FITS::FitsArrayOption = FITS::NoOpt) const;
00413         //     <group>
00414         // Use these versions if you are reading/writing "chunk by
00415         // chunk." No FtoC option is available. You are responsible for
00416         // ensuring that npixels corresponds to he number actually read or
00417         // written. Note that copy() turns blanks into NaN's.
00418         int store(const TYPE *source, int npixels);
00419         void copy(double *target, int npixels) const;
00420         void copy(float *target, int npixels) const;
00421         void move(TYPE *target, int npixels) const;
00422         //     </group>
00423         // </group>
00424         //<group>
00425         int write_priArr_hdr( FitsOutput &fout, int simple, int bitpix,     
00426                               int naxis, long naxes[], int extend );            
00427         //</group>
00428         // The `read()' and `write()' functions control reading and writing data
00429         // from the external FITS I/O medium into the FITS array.  Appropriate
00430         // conversions are made between FITS and local data representations.  One
00431         // can read the entire array into memory, or one can only read portions of
00432         // the array.  In the latter case, one must specify that the next N
00433         // elements are to be read or written.  Note that the number of elements
00434         // must be specified, NOT the number of bytes.  If one reads portions of
00435         // the array, as opposed to the entire array, only that portion is in
00436         // memory at a given time.  One can still access the elements of the array
00437         // via the `()' and `data()' functions, as if the entire array was in
00438         // memory; obviously care must be taken in this case to access only those
00439         // portions that are actually in memory.
00440         //<group>
00441         virtual int read(); 
00442         virtual int read( int ); 
00443         virtual int write(FitsOutput &); 
00444         virtual OFF_T set_next(OFF_T);
00445         //</group>
00446         //### if these, even as interspersed comments, cxx2html repeats the global
00447         //# group info..
00448         //# read: read entire array into memory
00449         //# read() read next N elements into memory
00450         //# write; write current data
00451         //# set_next(): prepare to write next N elements
00452 
00453     protected:
00454         // construct from a FitsInput with given HDU type
00455         PrimaryArray(FitsInput &, FITS::HDUType, 
00456                      FITSErrorHandler errhandler = FITSError::defaultHandler);
00457         // construct from a FitsKeywordList with given HDU type
00458         PrimaryArray(FitsKeywordList &, FITS::HDUType, 
00459                      FITSErrorHandler errhandler = FITSError::defaultHandler);
00460                           
00461         // construct witout FitsKeywordList for given HDU type( for ImageExtension and PrimaryGroup)
00462         PrimaryArray(FITS::HDUType, 
00463                      FITSErrorHandler errhandler = FITSError::defaultHandler);
00464 
00465 
00466         double bscale_x;
00467         double bzero_x;
00468         char *bunit_x;
00469         Bool isablank_x;
00470         Int blank_x;
00471         char **ctype_x;
00472         double *crpix_x;
00473         double *crota_x;
00474         double *crval_x;
00475         double *cdelt_x;
00476         double datamax_x;
00477         double datamin_x;
00478         OFF_T totsize;
00479 
00480         int *factor; // factors needed to compute array position offsets
00481 
00482         // compute a linear offset from array indicies
00483         //<group>
00484         int offset(int, int) const; 
00485         int offset(int, int, int) const; 
00486         int offset(int, int, int, int) const; 
00487         int offset(int, int, int, int, int) const; 
00488         //</group>
00489         OFF_T alloc_elems; // current number of allocated elements
00490         OFF_T beg_elem; // offset of first element in the buffer
00491         OFF_T end_elem; // offset of last element in the buffer
00492         // the allocated array
00493         TYPE *array;
00494 
00495         void pa_assign();
00496 };
00497 
00498 typedef PrimaryArray<unsigned char> BytePrimaryArray;
00499 typedef PrimaryArray<short> ShortPrimaryArray;
00500 typedef PrimaryArray<FitsLong> LongPrimaryArray;
00501 typedef PrimaryArray<float> FloatPrimaryArray;
00502 typedef PrimaryArray<double> DoublePrimaryArray;
00503 
00504 
00505 //<summary> IMAGE extension of given type </summary>
00506 //<templating>
00507 // <li> typedef ImageExtension<unsigned char> ByteImageExtension;
00508 // <li> typedef ImageExtension<short> ShortImageExtension;
00509 // <li> typedef ImageExtension<FitsLong> LongImageExtension;
00510 // <li> typedef ImageExtension<float> FloatImageExtension;
00511 // <li> typedef ImageExtension<double> DoubleImageExtension;
00512 //</templating>
00513 
00514 template <class TYPE>
00515 class ImageExtension : public PrimaryArray<TYPE> {
00516     public:
00517         typedef TYPE ElementType;
00518 
00519         ImageExtension(FitsInput &, 
00520                        FITSErrorHandler errhandler = FITSError::defaultHandler);
00521         ImageExtension(FitsKeywordList &, 
00522                        FITSErrorHandler errhandler = FITSError::defaultHandler);
00523         // constructor for header consisted required keywords only                       
00524         ImageExtension(FITSErrorHandler errhandler = FITSError::defaultHandler);
00525 
00526         ~ImageExtension();
00527         char *xtension()        { return xtension_x; }
00528         char *extname()         { return extname_x; }
00529         Int extver()            { return extver_x; }
00530         Int extlevel()  { return extlevel_x; }
00531         Int pcount()            { return pcount_x; }
00532         Int gcount()            { return gcount_x; }
00533         // write required keywords for ImageExtension
00534         int write_imgExt_hdr( FitsOutput &fout,
00535             int bitpix, int naxis, long *naxes);     
00536     protected:
00537         char *xtension_x;
00538         char *extname_x;
00539         Int extver_x;
00540         Int extlevel_x;
00541         Int pcount_x;
00542         Int gcount_x;
00543 
00544     private:
00545         void ie_assign();
00546 
00547         //# Make members in parent known
00548     protected:
00549         using PrimaryArray<TYPE>::assign;
00550         using PrimaryArray<TYPE>::errmsg;
00551         using PrimaryArray<TYPE>::init_data_unit;
00552         using PrimaryArray<TYPE>::pa_assign;
00553         using PrimaryArray<TYPE>::char_null;
00554         using PrimaryArray<TYPE>::kwlist_;
00555         using PrimaryArray<TYPE>::errfn;
00556         using PrimaryArray<TYPE>::hdu_type;
00557         using PrimaryArray<TYPE>::data_type;
00558         using PrimaryArray<TYPE>::fits_data_size;
00559         using PrimaryArray<TYPE>::fits_item_size;
00560         using PrimaryArray<TYPE>::array;
00561         using PrimaryArray<TYPE>::BADOPER;
00562 };
00563 
00564 typedef ImageExtension<unsigned char> ByteImageExtension;
00565 typedef ImageExtension<short> ShortImageExtension;
00566 typedef ImageExtension<FitsLong> LongImageExtension;
00567 typedef ImageExtension<float> FloatImageExtension;
00568 typedef ImageExtension<double> DoubleImageExtension;
00569 
00570 //<summary> Random Group datastructure </summary>
00571 //<synopsis>
00572 // A Random Group Structure is represented by the following:
00573 //<srcblock>
00574 //      struct GroupData {
00575 //              <Type> group_parms [PCOUNT];
00576 //              <Type> data_array [NAXIS2][NAXIS3]...[NAXISN];
00577 //      } group_data[GCOUNT];
00578 //</srcblock>
00579 //</synopsis>
00580 //<templating>
00581 //#until cxx2html can handle this, duplicate
00582 // <li>typedef PrimaryGroup<unsigned char> BytePrimaryGroup;
00583 // <li> typedef PrimaryGroup<short> ShortPrimaryGroup;
00584 // <li> typedef PrimaryGroup<FitsLong> LongPrimaryGroup;
00585 // <li> typedef PrimaryGroup<float> FloatPrimaryGroup;
00586 // <li> typedef PrimaryGroup<double> DoublePrimaryGroup;
00587 //</templating>
00588 //<note role=warning>
00589 // Please note that the NOST has deprecated the Random Group 
00590 // datastructure, it has been replaced by the much more powerfull
00591 // BINTABLE extension.
00592 //</note>
00593 template <class TYPE>
00594 class PrimaryGroup : public PrimaryArray<TYPE> {
00595     public:
00596         PrimaryGroup(FitsInput &, 
00597                      FITSErrorHandler errhandler = FITSError::defaultHandler);
00598         PrimaryGroup(FitsKeywordList &, 
00599                      FITSErrorHandler errhandler = FITSError::defaultHandler);
00600         // constructor for header consisted required keywords only
00601         PrimaryGroup(FITSErrorHandler errhandler = FITSError::defaultHandler);
00602                          
00603         ~PrimaryGroup();
00604 
00605         // Return basic parameters of a random group
00606         //<group>
00607         Int gcount() const         { return gcount_x; }
00608         Int pcount()  const        { return pcount_x; }
00609         char *ptype(int n)  const  { return ptype_x[n]; }
00610         double pscal(int n)  const { return pscal_x[n]; }
00611         double pzero(int n)  const { return pzero_x[n]; }
00612         //</group>
00613 
00614         Int currgroup() const      { return current_group; }
00615 
00616         double parm(int); // return physical parms
00617         TYPE & rawparm(int); // access raw parms
00618 
00619         void storeparm(const TYPE *source);
00620         void copyparm(double *target) const;
00621         void copyparm(float *target) const;
00622         void moveparm(TYPE *target) const;
00623 
00624         // read, or write the next group
00625         //<group>
00626         int read();
00627         int write(FitsOutput &);
00628         //</group>
00629         // write the required keywords for PrimaryGroup
00630         //<group>
00631         int write_priGrp_hdr( FitsOutput &fout, int simple, int bitpix,   
00632             int naxis, long naxes[], long pcount, long gcount ); 
00633    //</group>
00634         
00635         // disable these functions, since they
00636         // are inherited from PrimaryArray
00637         //<group>
00638         OFF_T set_next(OFF_T) { return 0; }
00639         int read(int) { return -1; }
00640         //</group>
00641 
00642     protected:
00643         Int pcount_x;
00644         Int gcount_x;
00645         char **ptype_x;
00646         double *pscal_x;
00647         double *pzero_x;
00648         TYPE *group_parm;
00649         Int current_group;      
00650 
00651     private:
00652         void pg_assign();
00653 
00654         //# Make members in parent known
00655     protected:
00656         using PrimaryArray<TYPE>::assign;
00657         using PrimaryArray<TYPE>::errmsg;
00658         using PrimaryArray<TYPE>::init_data_unit;
00659         using PrimaryArray<TYPE>::pa_assign;
00660         using PrimaryArray<TYPE>::asgdbl;
00661         using PrimaryArray<TYPE>::nelements;
00662         using PrimaryArray<TYPE>::localitemsize;
00663         using PrimaryArray<TYPE>::fitsitemsize;
00664         using PrimaryArray<TYPE>::read_data;
00665         using PrimaryArray<TYPE>::write_data;
00666         using PrimaryArray<TYPE>::char_null;
00667         using PrimaryArray<TYPE>::kwlist_;
00668         using PrimaryArray<TYPE>::errfn;
00669         using PrimaryArray<TYPE>::err_status;
00670         using PrimaryArray<TYPE>::hdu_type;
00671         using PrimaryArray<TYPE>::data_type;
00672         using PrimaryArray<TYPE>::fits_data_size;
00673         using PrimaryArray<TYPE>::fits_item_size;
00674         using PrimaryArray<TYPE>::array;
00675         using PrimaryArray<TYPE>::totsize;
00676         using PrimaryArray<TYPE>::dimn;
00677         using PrimaryArray<TYPE>::no_dims;
00678         using PrimaryArray<TYPE>::factor;
00679         using PrimaryArray<TYPE>::ctype_x;
00680         using PrimaryArray<TYPE>::crpix_x;
00681         using PrimaryArray<TYPE>::crota_x;
00682         using PrimaryArray<TYPE>::crval_x;
00683         using PrimaryArray<TYPE>::cdelt_x;
00684         using PrimaryArray<TYPE>::BADOPER;
00685         using PrimaryArray<TYPE>::OK;
00686         using PrimaryArray<TYPE>::NOMEM;
00687         using PrimaryArray<TYPE>::BADIO;
00688 };
00689 
00690 typedef PrimaryGroup<unsigned char> BytePrimaryGroup;
00691 typedef PrimaryGroup<short> ShortPrimaryGroup;
00692 typedef PrimaryGroup<FitsLong> LongPrimaryGroup;
00693 typedef PrimaryGroup<float> FloatPrimaryGroup;
00694 typedef PrimaryGroup<double> DoublePrimaryGroup;
00695 
00696 //<summary> Primary Table structure </summary>
00697 //<templating>
00698 // <li> typedef PrimaryTable<unsigned char> BytePrimaryTable;
00699 // <li> typedef PrimaryTable<short> ShortPrimaryTable;
00700 // <li> typedef PrimaryTable<FitsLong> LongPrimaryTable;
00701 // <li> typedef PrimaryTable<float> FloatPrimaryTable;
00702 // <li> typedef PrimaryTable<double> DoublePrimaryTable;
00703 //</templating>
00704 
00705 template <class TYPE>
00706 class PrimaryTable : public PrimaryArray<TYPE> {
00707     public:
00708         typedef TYPE ElementType;
00709 
00710         PrimaryTable(FitsInput &, 
00711                        FITSErrorHandler errhandler = FITSError::defaultHandler);
00712         PrimaryTable(FitsKeywordList &, 
00713                        FITSErrorHandler errhandler = FITSError::defaultHandler);
00714         // constructor for header consisted required keywords only                       
00715         PrimaryTable(FITSErrorHandler errhandler = FITSError::defaultHandler);
00716 
00717         ~PrimaryTable();
00718         // write required keywords for PrimaryTable
00719         int write_priTable_hdr( FitsOutput &fout,
00720             int bitpix, int naxis, long *naxes);     
00721 
00722         int read();
00723         int write(FitsOutput &){ return -1; }
00724 
00725         char* object() const       { return object_x; }
00726         char* telescop()  const    { return telescop_x; }
00727         char* instrume()  const    { return instrume_x; }
00728         char* dateobs()  const { return dateobs_x; }
00729         char* datemap()  const { return datemap_x; }
00730         char* bunit()  const       { return bunit_x; }
00731         float bscal()  const { return bscale_x; }
00732         float bzero()  const { return bzero_x; }
00733         float equinox()  const { return equinox_x; }
00734         float altrpix()  const { return altrpix_x; }
00735 
00736     protected:
00737         char* object_x;      //OBJECT
00738         char* telescop_x;    //TELESCOP
00739         char* instrume_x;    //INSTRUME
00740         char* dateobs_x;    //DATE-OBS
00741         char* datemap_x;    //DATE-MAP
00742         Float bscale_x;      //BSCALE
00743         Float bzero_x;       //BZERO
00744         char* bunit_x;       //BUNIT
00745         Float equinox_x;     //EQUINOX
00746         Float altrpix_x;     //ALTRPIX
00747 
00748 
00749     private:
00750         void pt_assign();
00751 
00752         //# Make members in parent known
00753     protected:
00754         using PrimaryArray<TYPE>::assign;
00755         using PrimaryArray<TYPE>::errmsg;
00756         using PrimaryArray<TYPE>::init_data_unit;
00757         using PrimaryArray<TYPE>::pa_assign;
00758         using PrimaryArray<TYPE>::asgdbl;
00759         using PrimaryArray<TYPE>::nelements;
00760         using PrimaryArray<TYPE>::localitemsize;
00761         using PrimaryArray<TYPE>::fitsitemsize;
00762         using PrimaryArray<TYPE>::read_data;
00763         using PrimaryArray<TYPE>::write_data;
00764         using PrimaryArray<TYPE>::char_null;
00765         using PrimaryArray<TYPE>::kwlist_;
00766         using PrimaryArray<TYPE>::errfn;
00767         using PrimaryArray<TYPE>::err_status;
00768         using PrimaryArray<TYPE>::hdu_type;
00769         using PrimaryArray<TYPE>::data_type;
00770         using PrimaryArray<TYPE>::fits_data_size;
00771         using PrimaryArray<TYPE>::fits_item_size;
00772         using PrimaryArray<TYPE>::array;
00773         using PrimaryArray<TYPE>::totsize;
00774         using PrimaryArray<TYPE>::dimn;
00775         using PrimaryArray<TYPE>::no_dims;
00776         using PrimaryArray<TYPE>::factor;
00777         using PrimaryArray<TYPE>::ctype_x;
00778         using PrimaryArray<TYPE>::crpix_x;
00779         using PrimaryArray<TYPE>::crota_x;
00780         using PrimaryArray<TYPE>::crval_x;
00781         using PrimaryArray<TYPE>::cdelt_x;
00782         using PrimaryArray<TYPE>::BADOPER;
00783         using PrimaryArray<TYPE>::OK;
00784         using PrimaryArray<TYPE>::NOMEM;
00785         using PrimaryArray<TYPE>::BADIO;
00786 };
00787 
00788 typedef PrimaryTable<unsigned char> BytePrimaryTable;
00789 typedef PrimaryTable<short> ShortPrimaryTable;
00790 typedef PrimaryTable<FitsLong> LongPrimaryTable;
00791 typedef PrimaryTable<float> FloatPrimaryTable;
00792 typedef PrimaryTable<double> DoublePrimaryTable;
00793 
00794 //<summary>  base class for generalized exentensions HDU </summary>
00795 
00796 class ExtensionHeaderDataUnit : public HeaderDataUnit {
00797     public:
00798         ExtensionHeaderDataUnit(FitsInput &, 
00799                                 FITSErrorHandler errhandler = FITSError::defaultHandler);
00800         ExtensionHeaderDataUnit(FitsKeywordList &, 
00801                                 FITSErrorHandler errhandler = FITSError::defaultHandler);
00802         ~ExtensionHeaderDataUnit();
00803         char *xtension()        { return xtension_x; }
00804         char *extname()         { return extname_x; }
00805         Int extver()            { return extver_x; }
00806         Int extlevel()  { return extlevel_x; }
00807         Int pcount()            { return pcount_x; }
00808         Int gcount()            { return gcount_x; }
00809 
00810         // read next N bytes into addr
00811         int read(char *addr, int nbytes) {
00812             return read_data(addr, Int(nbytes)); }
00813         // write next N bytes from addr to the FITS output fout
00814         int write(FitsOutput &fout, char *addr, int nbytes) {
00815             return write_data(fout,addr,nbytes); }
00816 
00817     protected:
00818         ExtensionHeaderDataUnit(FitsInput &, FITS::HDUType, 
00819                                 FITSErrorHandler errhandler = FITSError::defaultHandler);
00820         ExtensionHeaderDataUnit(FitsKeywordList &, FITS::HDUType, 
00821                                 FITSErrorHandler errhandler = FITSError::defaultHandler);
00822         // This constructor is used for writing only required keywords.
00823         ExtensionHeaderDataUnit(FITS::HDUType, 
00824                                 FITSErrorHandler errhandler = FITSError::defaultHandler);
00825 
00826         char *xtension_x;
00827         char *extname_x;
00828         Int extver_x;
00829         Int extlevel_x;
00830         Int pcount_x;
00831         Int gcount_x;
00832 
00833     private:
00834         void ex_assign();
00835 };
00836 
00837 //<summary> helper class </summary>
00838 
00839 class FitsBase {
00840         friend class BinaryTableExtension;
00841         friend class AsciiTableExtension;
00842     public:
00843         FitsBase(const FITS::ValueType &t, int n) : no_elements(n), 
00844                 data_type(t) { }
00845         virtual ~FitsBase();
00846 
00847         unsigned int nelements() const    { return (unsigned int)no_elements; }
00848         virtual int fitsfieldsize() const = 0;
00849         virtual int localfieldsize() const = 0;
00850         virtual void *data() = 0;
00851         virtual int dims() const;
00852         virtual int dim(int n) const;
00853         virtual int *vdim();
00854         FITS::ValueType fieldtype() const { return data_type; }
00855 
00856         static FitsBase *make(const FITS::ValueType &, int = 1);
00857         static FitsBase *make(const FITS::ValueType &, int, int *);
00858         static FitsBase *make(FitsBase &);
00859 
00860         FitsBase & operator = (FitsBase &);
00861         virtual void show(std::ostream &) = 0;
00862 
00863     protected:
00864         int no_elements; // the number of elements in the field
00865         FITS::ValueType data_type;
00866         virtual void setaddr(void **) = 0;
00867 };
00868 
00869 inline std::ostream & operator << (std::ostream &o, FitsBase &x) {
00870         x.show(o); return o;
00871 }
00872 
00873 //<summary> helper class </summary>
00874 //<note>
00875 // Note that FitsField does not allocate space for the data.
00876 // Space is external to FitsField and its address is set via the
00877 // setaddr function.
00878 //</note>
00879 
00880 template <class TYPE>
00881 class FitsField : public FitsBase {
00882     public:
00883         FitsField(int n = 1) :
00884             FitsBase(FITS::getfitstype(NoConvert<TYPE>()),n), field(0) { }
00885         ~FitsField();
00886 
00887         TYPE & operator () () { return (*field)[0]; }
00888         TYPE & operator () (int i) { return (*field)[i]; }
00889         FitsField<TYPE> & operator = (const TYPE &x) {
00890                                         (*field)[0] = x; return *this; }
00891 
00892         int fitsfieldsize() const;
00893         int localfieldsize() const;
00894 
00895         void *data();
00896 
00897         void show(std::ostream &);
00898 
00899     protected:
00900         TYPE **field;
00901         void setaddr(void **addr);
00902 };
00903 
00904 //<summary> helper class </summary>
00905 //<templating>
00906 //#until cxx2html can handle this, duplicate
00907 // <li> typedef FitsField<FitsLogical> LogicalFitsField;
00908 // <li> typedef FitsField<FitsBit> BitFitsField;
00909 // <li> typedef FitsField<char> CharFitsField;
00910 // <li> typedef FitsField<unsigned char> ByteFitsField;
00911 // <li> typedef FitsField<short> ShortFitsField;
00912 // <li> typedef FitsField<FitsLong> LongFitsField;
00913 // <li> typedef FitsField<float> FloatFitsField;
00914 // <li> typedef FitsField<double> DoubleFitsField;
00915 // <li> typedef FitsField<Complex> ComplexFitsField;
00916 // <li> typedef FitsField<IComplex> IComplexFitsField;
00917 // <li> typedef FitsField<DComplex> DComplexFitsField;
00918 // <li> typedef FitsField<FitsVADesc> VADescFitsField;
00919 //</templating>
00920 //<note role=caution> 
00921 // Bit fields require special treatment
00922 //</note>
00923 
00924 template <> class FitsField<FitsBit> : public FitsBase {
00925     public:
00926         FitsField(int n = 1);
00927         ~FitsField();
00928 
00929         FitsField<FitsBit> & operator () () { byte_offset = 0; mask = 0200;
00930                 return *this; }
00931 
00932         FitsField<FitsBit> & operator () (unsigned i) {
00933             byte_offset = i / 8; mask = 0200 >> (i % 8); return *this; }
00934 
00935         FitsField<FitsBit> & operator = (unsigned i) {
00936             (*field)[byte_offset] =
00937                 (i == 0 ? ((*field)[byte_offset] & ~mask) :
00938                           ((*field)[byte_offset] | mask)); return *this; }
00939 
00940         int fitsfieldsize() const;
00941         int localfieldsize() const;
00942 
00943         operator int() { return (((*field)[byte_offset] & mask) != 0); }
00944 
00945         void *data();
00946 
00947         void show(std::ostream &);
00948 
00949     protected:
00950         FitsBit **field;
00951         unsigned char mask;
00952         int byte_offset;
00953         void setaddr(void **addr);
00954 };
00955 
00956 typedef FitsField<FitsLogical> LogicalFitsField;
00957 typedef FitsField<FitsBit> BitFitsField;
00958 typedef FitsField<char> CharFitsField;
00959 typedef FitsField<unsigned char> ByteFitsField;
00960 typedef FitsField<short> ShortFitsField;
00961 typedef FitsField<FitsLong> LongFitsField;
00962 typedef FitsField<float> FloatFitsField;
00963 typedef FitsField<double> DoubleFitsField;
00964 typedef FitsField<Complex> ComplexFitsField;
00965 typedef FitsField<IComplex> IComplexFitsField;
00966 typedef FitsField<DComplex> DComplexFitsField;
00967 typedef FitsField<FitsVADesc> VADescFitsField;
00968 
00969 //<summary> FITS array of given type </summary>
00970 template <class TYPE>
00971 class FitsArray : public FitsField<TYPE> {
00972     public:
00973         FitsArray(int, const int *);
00974         ~FitsArray();
00975         TYPE & operator () (int d0, int d1);
00976         TYPE & operator () (int, int, int);
00977         TYPE & operator () (int, int, int, int);
00978         TYPE & operator () (int, int, int, int, int);
00979         int dims() const;
00980         int dim(int n) const;
00981         int *vdim();
00982     protected:
00983         int no_dims;
00984         int *dimn;
00985         int *factor;
00986 
00987         //# Make members in parent known
00988     protected:
00989         using FitsField<TYPE>::no_elements;
00990         using FitsField<TYPE>::field;
00991 };
00992 
00993 //<summary> FITS array of FitsBit type </summary>
00994 
00995 //<templating>
00996 //#until cxx2html can handle this, duplicate:
00997 // <li> typedef FitsArray<FitsLogical> LogicalFitsArray;
00998 // <li> typedef FitsArray<FitsBit> BitFitsArray;
00999 // <li> typedef FitsArray<char> CharFitsArray;
01000 // <li> typedef FitsArray<unsigned char> ByteFitsArray;
01001 // <li> typedef FitsArray<short> ShortFitsArray;
01002 // <li> typedef FitsArray<FitsLong> LongFitsArray;
01003 // <li> typedef FitsArray<float> FloatFitsArray;
01004 // <li> typedef FitsArray<double> DoubleFitsArray;
01005 // <li> typedef FitsArray<Complex> ComplexFitsArray;
01006 // <li> typedef FitsArray<IComplex> IComplexFitsArray;
01007 // <li> typedef FitsArray<DComplex> DComplexFitsArray;
01008 // <li> typedef FitsArray<FitsVADesc> VADescFitsArray;
01009 //</templating>
01010 //<note>
01011 // We must specify a FitsArray<FitsBit> as a specialization.
01012 //</note>
01013 
01014 template <> class FitsArray<FitsBit> : public FitsField<FitsBit> {
01015     public:
01016         FitsArray(int, const int *);
01017         ~FitsArray();
01018         FitsField<FitsBit> & operator () (int d0, int d1);
01019         FitsField<FitsBit> & operator () (int, int, int);
01020         FitsField<FitsBit> & operator () (int, int, int, int);
01021         FitsField<FitsBit> & operator () (int, int, int, int, int);
01022 //# Disabled for now - we might eventually want to put varargs support back
01023 //#     FitsField<FitsBit> & operator () (int, int, int, int, int, int ...);
01024 
01025         int dims() const;
01026         int dim(int n) const;
01027         int *vdim();
01028     protected:
01029         int no_dims;
01030         int *dimn;
01031         int *factor;
01032 };
01033 
01034 typedef FitsArray<FitsLogical> LogicalFitsArray;
01035 typedef FitsArray<FitsBit> BitFitsArray;
01036 typedef FitsArray<char> CharFitsArray;
01037 typedef FitsArray<unsigned char> ByteFitsArray;
01038 typedef FitsArray<short> ShortFitsArray;
01039 typedef FitsArray<FitsLong> LongFitsArray;
01040 typedef FitsArray<float> FloatFitsArray;
01041 typedef FitsArray<double> DoubleFitsArray;
01042 typedef FitsArray<Complex> ComplexFitsArray;
01043 typedef FitsArray<IComplex> IComplexFitsArray;
01044 typedef FitsArray<DComplex> DComplexFitsArray;
01045 typedef FitsArray<FitsVADesc> VADescFitsArray;
01046 
01047 //<summary> BINTABLE extension </summary>
01048 
01049 class BinaryTableExtension : public ExtensionHeaderDataUnit {
01050     public:
01051         BinaryTableExtension(FitsInput &, 
01052                              FITSErrorHandler errhandler = FITSError::defaultHandler);
01053                                   
01054         BinaryTableExtension(FitsKeywordList &, 
01055                              FITSErrorHandler errhandler = FITSError::defaultHandler);
01056         // constructor to match write_bintbl_hdr()                        
01057         BinaryTableExtension( FITSErrorHandler errhandler = FITSError::defaultHandler);
01058 
01059         virtual ~BinaryTableExtension();
01060 
01061         // return basic elements of a table
01062         //<group>
01063         Int nrows() const               { return dim(1); }
01064         Int ncols() const               { return tfields_x; }
01065         uInt rowsize() const            { return fitsrowsize; }
01066         Int tfields() const             { return tfields_x; }
01067         const char *tform(int n) const  { return tform_x[n]; }
01068         double tscal(int n) const       { return tscal_x[n]; }
01069         double tzero(int n) const       { return tzero_x[n]; }
01070         Bool isatnull(int n) const      { return isatnull_x[n]; }
01071         Int  tnull(int n) const         { return tnull_x[n]; }
01072         const char *ttype(int n) const  { return ttype_x[n]; }  
01073         const char *tunit(int n) const  { return tunit_x[n]; }
01074         const char *tdisp(int n) const  { return tdisp_x[n]; }
01075         const char *tdim(int n) const   { return tdim_x[n]; }
01076         const char *ctype(int n) const  { return ctype_x[n]; }
01077         double crpix(int n) const       { return crpix_x[n]; }
01078         double crota(int n) const       { return crota_x[n]; }
01079         double crval(int n) const       { return crval_x[n]; }
01080         double cdelt(int n) const       { return cdelt_x[n]; }
01081         Int theap() const               { return theap_x; }
01082         const char *author() const      { return author_x; }
01083         const char *referenc() const    { return referenc_x; }
01084         //</group>
01085 
01086         // binds a FitsField to a column
01087         int bind(int, FitsBase &); 
01088 
01089         // row selector functions
01090         //<group>
01091         BinaryTableExtension & operator ++ ();  
01092         BinaryTableExtension & operator -- ();
01093         BinaryTableExtension & operator () (int);
01094         //</group>
01095 
01096         // read entire table into memory
01097         int read();
01098         // read next N rows into memory
01099         int read(int);
01100         // prepare to write the next N rows
01101         int set_next(int);       
01102         // write current rows
01103         int write(FitsOutput &);
01104         // create a binary table header without using FitsKeywordList objet.
01105         int write_binTbl_hdr(FitsOutput &, long, int, const char**,
01106                              const char**, const char**, const char*, long );
01107 
01108         // select a field
01109         FitsBase &field(int i) const    { return *fld[i]; }
01110         // get current row
01111         Int currrow() const             { return curr_row; }
01112         // sets field addresses in the current row
01113         //void set_fitsrow(Int);
01114 
01115     protected:
01116         BinaryTableExtension(FitsInput &, FITS::HDUType, 
01117                              FITSErrorHandler errhandler = FITSError::defaultHandler);
01118         BinaryTableExtension(FitsKeywordList &, FITS::HDUType, 
01119                              FITSErrorHandler errhandler = FITSError::defaultHandler);
01120         BinaryTableExtension(FITS::HDUType, 
01121                              FITSErrorHandler errhandler = FITSError::defaultHandler);
01122 
01123         Int tfields_x;
01124         char **tform_x;
01125         double *tscal_x;
01126         double *tzero_x;
01127         Bool *isatnull_x;
01128         Int *tnull_x;
01129         char **ttype_x; 
01130         char **tunit_x;
01131         char **tdisp_x;
01132         char **tdim_x;
01133         char **ctype_x;
01134         double *crpix_x;
01135         double *crota_x;
01136         double *crval_x;
01137         double *cdelt_x;
01138         Int nAxis;
01139         Int theap_x;
01140         char *author_x;
01141         char *referenc_x;
01142 
01143         // read and write the next FITS data row
01144         //<group>
01145         virtual int readrow();  
01146         virtual int writerow(FitsOutput &);
01147         //</group>
01148         unsigned char *fitsrow; // the FITS data row buffer
01149         uInt *fits_offset;      // Offsets to the fields within a FITS row
01150         uInt fitsrowsize;       // size in bytes of a FITS data row
01151         Bool isoptimum;         // tells whether optimum case exists or not
01152 
01153         // sets field addresses in the current row
01154         void set_fitsrow(Int);
01155 
01156         unsigned char *table;   // the table in local format
01157         uInt tablerowsize;      // size in bytes of a table row
01158         uInt alloc_row;         // number of currently allocated rows
01159         Int beg_row;            // range of rows currently in memory
01160         Int end_row;
01161         Int curr_row;
01162         FitsBase **fld;         // The array of fields
01163         uInt *table_offset;     // Offsets to the fields within a table row
01164         // data addresses of fields of current row
01165         void **data_addr;       
01166 
01167     private:
01168         void bt_assign();
01169 };
01170 
01171 
01172 //<summary> (ascii) TABLE extension </summary>
01173 
01174 class AsciiTableExtension : public BinaryTableExtension {
01175     public:
01176         AsciiTableExtension(FitsInput &, 
01177                             FITSErrorHandler errhandler = FITSError::defaultHandler);
01178         AsciiTableExtension(FitsKeywordList &, 
01179                             FITSErrorHandler errhandler = FITSError::defaultHandler);
01180         AsciiTableExtension(FITSErrorHandler errhandler = FITSError::defaultHandler);
01181 
01182         ~AsciiTableExtension();
01183 
01184         //# special overriden functions for ascii TABLE only
01185         // position in which column starts
01186         Int tbcol(int n)        { return tbcol_x[n]; }
01187         // ascii string that represents the NULL value
01188         char *tnull(int n)      { return tnulla_x[n]; }
01189         // write the required keywords for ASCIITableExtension
01190         int write_ascTbl_hdr( FitsOutput &, long,
01191                               long, int, const char **, long *,
01192                               const char **, const char **, const char *e);   
01193 
01194     protected:
01195         Int *tbcol_x;
01196         char **tnulla_x;
01197         uInt *fits_width;       // widths of the fields within a FITS row
01198         char **format;          // converted formats of the fields
01199 
01200         // read and write the next FITS data row
01201         //<group>
01202         int readrow();          
01203         int writerow(FitsOutput &);
01204         //</group>  
01205 
01206     private:
01207         void at_assign();
01208 };
01209 
01210 
01211 } //# NAMESPACE CASA - END
01212 
01213 #ifndef CASACORE_NO_AUTO_TEMPLATES
01214 #include <fits/FITS/hdu.tcc>
01215 #endif //# CASACORE_NO_AUTO_TEMPLATES
01216 # endif