# Chapter 9  Specialized CFITSIO Interface Routines

The basic interface routines described previously are recommended for most uses, but the routines described in this chapter are also available if necessary. Some of these routines perform more specialized function that cannot easily be done with the basic interface routines while others duplicate the functionality of the basic routines but have a slightly different calling sequence. See Appendix B for the definition of each function parameter.

## 9.1 FITS File Access Routines

### 9.1.1 File Access

1
  Open an existing FITS file residing in core computer memory. This routine is analogous to fits_open_file. The ’filename’ is currently ignored by this routine and may be any arbitrary string. In general, the application must have preallocated an initial block of memory to hold the FITS file prior to calling this routine: ’memptr’ points to the starting address and ’memsize’ gives the initial size of the block of memory. ’mem_realloc’ is a pointer to an optional function that CFITSIO can call to allocate additional memory, if needed (only if mode = READWRITE), and is modeled after the standard C ’realloc’ function; a null pointer may be given if the initial allocation of memory is all that will be required (e.g., if the file is opened with mode = READONLY). The ’deltasize’ parameter may be used to suggest a minimum amount of additional memory that should be allocated during each call to the memory reallocation function. By default, CFITSIO will reallocate enough additional space to hold the entire currently defined FITS file (as given by the NAXISn keywords) or 1 FITS block (= 2880 bytes), which ever is larger. Values of deltasize less than 2880 will be ignored. Since the memory reallocation operation can be computationally expensive, allocating a larger initial block of memory, and/or specifying a larger deltasize value may help to reduce the number of reallocation calls and make the application program run faster. Note that values of the memptr and memsize pointers will be updated by CFITSIO if the location or size of the FITS file in memory should change as a result of allocating more memory.

      int fits_open_memfile / ffomem
          (fitsfile **fptr, const char *filename, int mode, void **memptr,
           size_t *memsize, size_t deltasize,
           void *(*mem_realloc)(void *p, size_t newsize), int *status)

2
  Create a new FITS file residing in core computer memory. This routine is analogous to fits_create_file. In general, the application must have preallocated an initial block of memory to hold the FITS file prior to calling this routine: ’memptr’ points to the starting address and ’memsize’ gives the initial size of the block of memory. ’mem_realloc’ is a pointer to an optional function that CFITSIO can call to allocate additional memory, if needed, and is modeled after the standard C ’realloc’ function; a null pointer may be given if the initial allocation of memory is all that will be required. The ’deltasize’ parameter may be used to suggest a minimum amount of additional memory that should be allocated during each call to the memory reallocation function. By default, CFITSIO will reallocate enough additional space to hold 1 FITS block (= 2880 bytes) and values of deltasize less than 2880 will be ignored. Since the memory reallocation operation can be computationally expensive, allocating a larger initial block of memory, and/or specifying a larger deltasize value may help to reduce the number of reallocation calls and make the application program run faster. Note that values of the memptr and memsize pointers will be updated by CFITSIO if the location or size of the FITS file in memory should change as a result of allocating more memory.

      int fits_create_memfile / ffimem
          (fitsfile **fptr, void **memptr,
           size_t *memsize, size_t deltasize,
           void *(*mem_realloc)(void *p, size_t newsize), int *status)

3
  Reopen a FITS file that was previously opened with fits_open_file or fits_create_file. The new fitsfile pointer may then be treated as a separate file, and one may simultaneously read or write to 2 (or more) different extensions in the same file. The fits_open_file routine (above) automatically detects cases where a previously opened file is being opened again, and then internally call fits_reopen_file, so programs should rarely need to explicitly call this routine.

      int fits_reopen_file / ffreopen
          (fitsfile *openfptr, fitsfile **newfptr, > int *status)

4
  Create a new FITS file, using a template file to define its initial size and structure. The template may be another FITS HDU or an ASCII template file. If the input template file name pointer is null, then this routine behaves the same as fits_create_file. The currently supported format of the ASCII template file is described under the fits_parse_template routine (in the general Utilities section)

      int fits_create_template / fftplt
          (fitsfile **fptr, char *filename, char *tpltfile > int *status)

5
  Parse the input filename or URL into its component parts, namely:
  - the file type (file://, ftp://, http://, etc),
  - the base input file name,
  - the name of the output file that the input file is to be copied to prior to opening,
  - the HDU or extension specification,
  - the filtering specifier,
  - the binning specifier,
  - the column specifier,
  - and the image pixel filtering specifier.
  A null pointer (0) may be be specified for any of the output string arguments that are not needed. Null strings will be returned for any components that are not present in the input file name. The calling routine must allocate sufficient memory to hold the returned character strings. Allocating the string lengths equal to FLEN_FILENAME is guaranteed to be safe. These routines are mainly for internal use by other CFITSIO routines.

      int fits_parse_input_url / ffiurl
          (char *filename, > char *filetype, char *infile, char *outfile, char
           *extspec, char *filter, char *binspec, char *colspec, int *status)

      int fits_parse_input_filename / ffifile
          (char *filename, > char *filetype, char *infile, char *outfile, char
           *extspec, char *filter, char *binspec, char *colspec, char *pixspec,
           int *status)

6
  Parse the input filename and return the HDU number that would be moved to if the file were opened with fits_open_file. The returned HDU number begins with 1 for the primary array, so for example, if the input filename = ‘myfile.fits[2]’ then hdunum = 3 will be returned. CFITSIO does not open the file to check if the extension actually exists if an extension number is specified. If an extension name is included in the file name specification (e.g. ‘myfile.fits[EVENTS]’ then this routine will have to open the FITS file and look for the position of the named extension, then close file again. This is not possible if the file is being read from the stdin stream, and an error will be returned in this case. If the filename does not specify an explicit extension (e.g. ’myfile.fits’) then hdunum = -99 will be returned, which is functionally equivalent to hdunum = 1. This routine is mainly used for backward compatibility in the ftools software package and is not recommended for general use. It is generally better and more efficient to first open the FITS file with fits_open_file, then use fits_get_hdu_num to determine which HDU in the file has been opened, rather than calling fits_parse_input_url followed by a call to fits_open_file.

       int fits_parse_extnum / ffextn
           (char *filename, > int *hdunum, int *status)

7
  Parse the input file name and return the root file name. The root name includes the file type if specified, (e.g. ’ftp://’ or ’http://’) and the full path name, to the extent that it is specified in the input filename. It does not include the HDU name or number, or any filtering specifications. The calling routine must allocate sufficient memory to hold the returned rootname character string. Allocating the length equal to FLEN_FILENAME is guaranteed to be safe.

       int fits_parse_rootname / ffrtnm
           (char *filename, > char *rootname, int *status);

8
  Test if the input file or a compressed version of the file (with a .gz, .Z, .z, or .zip extension) exists on disk. The returned value of the ’exists’ parameter will have 1 of the 4 following values:

         2:  the file does not exist, but a compressed version does exist
         1:  the disk file does exist
         0:  neither the file nor a compressed version of the file exist
        -1:  the input file name is not a disk file (could be a ftp, http,
             smem, or mem file, or a file piped in on the STDIN stream)

       int fits_file_exists / ffexist
           (char *filename, > int *exists, int *status);

9
  Flush any internal buffers of data to the output FITS file. These routines rarely need to be called, but can be useful in cases where other processes need to access the same FITS file in real time, either on disk or in memory. These routines also help to ensure that if the application program subsequently aborts then the FITS file will have been closed properly. The first routine, fits_flush_file is more rigorous and completely closes, then reopens, the current HDU, before flushing the internal buffers, thus ensuring that the output FITS file is identical to what would be produced if the FITS was closed at that point (i.e., with a call to fits_close_file). The second routine, fits_flush_buffer simply flushes the internal CFITSIO buffers of data to the output FITS file, without updating and closing the current HDU. This is much faster, but there may be circumstances where the flushed file does not completely reflect the final state of the file as it will exist when the file is actually closed.

  A typical use of these routines would be to flush the state of a FITS table to disk after each row of the table is written. It is recommend that fits_flush_file be called after the first row is written, then fits_flush_buffer may be called after each subsequent row is written. Note that this latter routine will not automatically update the NAXIS2 keyword which records the number of rows of data in the table, so this keyword must be explicitly updated by the application program after each row is written.

      int fits_flush_file / ffflus
          (fitsfile *fptr, > int *status)

      int fits_flush_buffer / ffflsh
          (fitsfile *fptr, 0, > int *status)

          (Note:  The second argument must be 0).

10
  Wrapper functions for global initialization and cleanup of the libcurl library used when accessing files with the HTTPS or FTPS protocols. If an HTTPS/FTPS file transfer is to be performed, it is recommended that you call the init function once near the start of your program before any file_open calls, and before creating any threads. The cleanup function should be called after all HTTPS/FTPS file accessing is completed, and after all threads are completed. The functions return 0 upon successful initialization and cleanup. These are NOT THREAD-SAFE.

      int fits_init_https / ffihtps
          ()

      int fits_cleanup_https / ffchtps
          ()

### 9.1.2 Download Utility Functions

These routines do not need to be called for normal file accessing. They are primarily intended to help with debugging and diagnosing issues which occur during file downloads. These routines are NOT THREAD-SAFE.

1
  Toggle the verbosity of the libcurl library diagnostic output when accessing files with the HTTPS or FTPS protocol. ‘flag’ = 1 turns the output on, 0 turns it off (the default).

       void fits_verbose_https / ffvhtps
            (int flag)

2
  If ‘flag’ is set to 1, this will display (to stderr) a progress bar during an https file download. (This is not yet implemented for other file transfer protocols.) ‘flag’ = 0 by default.

       void fits_show_download_progress / ffshdwn
            (int flag)

3
  The timeout setting (in seconds) determines the maximum time allowed for a net download to complete. If a download has not finished within the allowed time, the file transfer will terminate and the CFITSIO calling function will return with an error. Use fits_get_timeout will see the current timeout setting and fits_set_timeout to change the setting. This adjustmant may be particularly useful when having trouble downloading large files over slow connections.

       int fits_get_timeout / ffgtmo
           ()

       int fits_set_timeout / ffstmo
           (int seconds, > int *status)

## 9.2 HDU Access Routines

1
  Get the byte offsets in the FITS file to the start of the header and the start and end of the data in the CHDU. The difference between headstart and dataend equals the size of the CHDU. If the CHDU is the last HDU in the file, then dataend is also equal to the size of the entire FITS file. Null pointers may be input for any of the address parameters if their values are not needed.

      int fits_get_hduaddr / ffghad  (only supports files up to 2.1 GB in size)
           (fitsfile *fptr, > long *headstart, long *datastart, long *dataend,
            int *status)

      int fits_get_hduaddrll / ffghadll  (supports large files)
           (fitsfile *fptr, > LONGLONG *headstart, LONGLONG *datastart,
            LONGLONG *dataend, int *status)

2
  Create (append) a new empty HDU at the end of the FITS file. This is now the CHDU but it is completely empty and has no header keywords. It is recommended that fits_create_img or fits_create_tbl be used instead of this routine.

      int fits_create_hdu / ffcrhd
          (fitsfile *fptr, > int *status)

3
  Insert a new IMAGE extension immediately following the CHDU, or insert a new Primary Array at the beginning of the file. Any following extensions in the file will be shifted down to make room for the new extension. If the CHDU is the last HDU in the file then the new image extension will simply be appended to the end of the file. One can force a new primary array to be inserted at the beginning of the FITS file by setting status = PREPEND_PRIMARY prior to calling the routine. In this case the old primary array will be converted to an IMAGE extension. The new extension (or primary array) will become the CHDU. Refer to Chapter 9 for a list of pre-defined bitpix values.

      int fits_insert_img / ffiimg
          (fitsfile *fptr, int bitpix, int naxis, long *naxes, > int *status)

      int fits_insert_imgll / ffiimgll
          (fitsfile *fptr, int bitpix, int naxis, LONGLONG *naxes, > int *status)

4
  Insert a new ASCII or binary table extension immediately following the CHDU. Any following extensions will be shifted down to make room for the new extension. If there are no other following extensions then the new table extension will simply be appended to the end of the file. If the FITS file is currently empty then this routine will create a dummy primary array before appending the table to it. The new extension will become the CHDU. The tunit and extname parameters are optional and a null pointer may be given if they are not defined. When inserting an ASCII table with fits_insert_atbl, a null pointer may given for the *tbcol parameter in which case each column of the table will be separated by a single space character. Similarly, if the input value of rowlen is 0, then CFITSIO will calculate the default rowlength based on the tbcol and ttype values. Under normal circumstances, the nrows paramenter should have a value of 0; CFITSIO will automatically update the number of rows as data is written to the table. When inserting a binary table with fits_insert_btbl, if there are following extensions in the file and if the table contains variable length array columns then pcount must specify the expected final size of the data heap, otherwise pcount must = 0.

      int fits_insert_atbl / ffitab
          (fitsfile *fptr, LONGLONG rowlen, LONGLONG nrows, int tfields, char *ttype[],
           long *tbcol, char *tform[], char *tunit[], char *extname, > int *status)

      int fits_insert_btbl / ffibin
          (fitsfile *fptr, LONGLONG nrows, int tfields, char **ttype,
          char **tform, char **tunit, char *extname, long pcount, > int *status)

5
  Modify the size, dimensions, and/or data type of the current primary array or image extension. If the new image, as specified by the input arguments, is larger than the current existing image in the FITS file then zero fill data will be inserted at the end of the current image and any following extensions will be moved further back in the file. Similarly, if the new image is smaller than the current image then any following extensions will be shifted up towards the beginning of the FITS file and the image data will be truncated to the new size. This routine rewrites the BITPIX, NAXIS, and NAXISn keywords with the appropriate values for the new image.

      int fits_resize_img / ffrsim
          (fitsfile *fptr, int bitpix, int naxis, long *naxes, > int *status)

      int fits_resize_imgll / ffrsimll
          (fitsfile *fptr, int bitpix, int naxis, LONGLONG *naxes, > int *status)

6
  Copy the data (and not the header) from the CHDU associated with infptr to the CHDU associated with outfptr. This will overwrite any data previously in the output CHDU. This low level routine is used by fits_copy_hdu, but it may also be useful in certain application programs that want to copy the data from one FITS file to another but also want to modify the header keywords. The required FITS header keywords which define the structure of the HDU must be written to the output CHDU before calling this routine.

      int fits_copy_data / ffcpdt
          (fitsfile *infptr, fitsfile *outfptr, > int *status)

7
  Read or write a specified number of bytes starting at the specified byte offset from the start of the extension data unit. These low level routine are intended mainly for accessing the data in non-standard, conforming extensions, and should not be used for standard IMAGE, TABLE, or BINTABLE extensions.

      int fits_read_ext / ffgextn
          (fitsfile *fptr, LONGLONG offset, LONGLONG nbytes, void *buffer)
      int fits_write_ext / ffpextn
          (fitsfile *fptr, LONGLONG offset, LONGLONG nbytes, void *buffer)

8
  This routine forces CFITSIO to rescan the current header keywords that define the structure of the HDU (such as the NAXIS and BITPIX keywords) so that it reinitializes the internal buffers that describe the HDU structure. This routine is useful for reinitializing the structure of an HDU if any of the required keywords (e.g., NAXISn) have been modified. In practice it should rarely be necessary to call this routine because CFITSIO internally calls it in most situations.

      int fits_set_hdustruc / ffrdef
          (fitsfile *fptr, > int *status)   (DEPRECATED)

## 9.3 Specialized Header Keyword Routines

### 9.3.1 Header Information Routines

1
  Reserve space in the CHU for MOREKEYS more header keywords. This routine may be called to allocate space for additional keywords at the time the header is created (prior to writing any data). CFITSIO can dynamically add more space to the header when needed, however it is more efficient to preallocate the required space if the size is known in advance.

      int fits_set_hdrsize / ffhdef
          (fitsfile *fptr, int morekeys, > int *status)

2
  Return the number of keywords in the header (not counting the END keyword) and the current position in the header. The position is the number of the keyword record that will be read next (or one greater than the position of the last keyword that was read). A value of 1 is returned if the pointer is positioned at the beginning of the header.

      int fits_get_hdrpos / ffghps
          (fitsfile *fptr, > int *keysexist, int *keynum, int *status)

### 9.3.2 Read and Write the Required Keywords

1
  Write the required extension header keywords into the CHU. These routines are not required, and instead the appropriate header may be constructed by writing each individual keyword in the proper sequence.

  The simpler fits_write_imghdr routine is equivalent to calling fits_write_grphdr with the default values of simple = TRUE, pcount = 0, gcount = 1, and extend = TRUE. The PCOUNT, GCOUNT and EXTEND keywords are not required in the primary header and are only written if pcount is not equal to zero, gcount is not equal to zero or one, and if extend is TRUE, respectively. When writing to an IMAGE extension, the SIMPLE and EXTEND parameters are ignored. It is recommended that fits_create_image or fits_create_tbl be used instead of these routines to write the required header keywords. The general fits_write_exthdr routine may be used to write the header of any conforming FITS extension.

      int fits_write_imghdr / ffphps
          (fitsfile *fptr, int bitpix, int naxis, long *naxes, > int *status)

      int fits_write_imghdrll / ffphpsll
          (fitsfile *fptr, int bitpix, int naxis, LONGLONG *naxes, > int *status)

      int fits_write_grphdr / ffphpr
          (fitsfile *fptr, int simple, int bitpix, int naxis, long *naxes,
           LONGLONG pcount, LONGLONG gcount, int extend, > int *status)

      int fits_write_grphdrll / ffphprll
          (fitsfile *fptr, int simple, int bitpix, int naxis, LONGLONG *naxes,
           LONGLONG pcount, LONGLONG gcount, int extend, > int *status)

      int fits_write_exthdr /ffphext
          (fitsfile *fptr, char *xtension, int bitpix, int naxis, long *naxes,
           LONGLONG pcount, LONGLONG gcount, > int *status)

2
  Write the ASCII table header keywords into the CHU. The optional TUNITn and EXTNAME keywords are written only if the input pointers are not null. A null pointer may given for the *tbcol parameter in which case a single space will be inserted between each column of the table. Similarly, if rowlen is given = 0, then CFITSIO will calculate the default rowlength based on the tbcol and ttype values.

      int fits_write_atblhdr / ffphtb
          (fitsfile *fptr, LONGLONG rowlen, LONGLONG nrows, int tfields, char **ttype,
           long *tbcol, char **tform, char **tunit, char *extname, > int *status)

3
  Write the binary table header keywords into the CHU. The optional TUNITn and EXTNAME keywords are written only if the input pointers are not null. The pcount parameter, which specifies the size of the variable length array heap, should initially = 0; CFITSIO will automatically update the PCOUNT keyword value if any variable length array data is written to the heap. The TFORM keyword value for variable length vector columns should have the form ’Pt(len)’ or ’1Pt(len)’ where ‘t’ is the data type code letter (A,I,J,E,D, etc.) and ‘len’ is an integer specifying the maximum length of the vectors in that column (len must be greater than or equal to the longest vector in the column). If ‘len’ is not specified when the table is created (e.g., the input TFORMn value is just ’1Pt’) then CFITSIO will scan the column when the table is first closed and will append the maximum length to the TFORM keyword value. Note that if the table is subsequently modified to increase the maximum length of the vectors then the modifying program is responsible for also updating the TFORM keyword value.

      int fits_write_btblhdr / ffphbn
          (fitsfile *fptr, LONGLONG nrows, int tfields, char **ttype,
           char **tform, char **tunit, char *extname, LONGLONG pcount, > int *status)

4
  Read the required keywords from the CHDU (image or table). When reading from an IMAGE extension the SIMPLE and EXTEND parameters are ignored. A null pointer may be supplied for any of the returned parameters that are not needed.

      int fits_read_imghdr / ffghpr
          (fitsfile *fptr, int maxdim, > int *simple, int *bitpix, int *naxis,
           long *naxes, long *pcount, long *gcount, int *extend, int *status)

      int fits_read_imghdrll / ffghprll
          (fitsfile *fptr, int maxdim, > int *simple, int *bitpix, int *naxis,
           LONGLONG *naxes, long *pcount, long *gcount, int *extend, int *status)

      int fits_read_atblhdr / ffghtb
          (fitsfile *fptr,int maxdim, > long *rowlen, long *nrows,
           int *tfields, char **ttype, LONGLONG *tbcol, char **tform, char **tunit,
           char *extname,  int *status)

      int fits_read_atblhdrll / ffghtbll
          (fitsfile *fptr,int maxdim, > LONGLONG *rowlen, LONGLONG *nrows,
           int *tfields, char **ttype, long *tbcol, char **tform, char **tunit,
           char *extname,  int *status)

      int fits_read_btblhdr / ffghbn
          (fitsfile *fptr, int maxdim, > long *nrows, int *tfields,
           char **ttype, char **tform, char **tunit, char *extname,
           long *pcount, int *status)

      int fits_read_btblhdrll / ffghbnll
          (fitsfile *fptr, int maxdim, > LONGLONG *nrows, int *tfields,
           char **ttype, char **tform, char **tunit, char *extname,
           long *pcount, int *status)

### 9.3.3 Write Keyword Routines

These routines simply append a new keyword to the header and do not check to see if a keyword with the same name already exists. In general it is preferable to use the fits_update_key routine to ensure that the same keyword is not written more than once to the header. See Appendix B for the definition of the parameters used in these routines.

1
  Write (append) a new keyword of the appropriate data type into the CHU. A null pointer may be entered for the comment parameter, which will cause the comment field of the keyword to be left blank. The flt, dbl, cmp, and dblcmp versions of this routine have the added feature that if the ’decimals’ parameter is negative, then the ’G’ display format rather then the ’E’ format will be used when constructing the keyword value, taking the absolute value of ’decimals’ for the precision. This will suppress trailing zeros, and will use a fixed format rather than an exponential format, depending on the magnitude of the value.

      int fits_write_key_str / ffpkys
          (fitsfile *fptr, char *keyname, char *value, char *comment,
           > int *status)

      int fits_write_key_[log, lng] /  ffpky[lj]
          (fitsfile *fptr, char *keyname, DTYPE numval, char *comment,
           > int *status)

      int fits_write_key_[flt, dbl, fixflg, fixdbl] / ffpky[edfg]
          (fitsfile *fptr, char *keyname, DTYPE numval, int decimals,
          char *comment, > int *status)

      int fits_write_key_[cmp, dblcmp, fixcmp, fixdblcmp] / ffpk[yc,ym,fc,fm]
          (fitsfile *fptr, char *keyname, DTYPE *numval, int decimals,
          char *comment, > int *status)

2
  Write (append) a string valued keyword into the CHU which may be longer than 68 characters in length. This uses the Long String Keyword convention that is described in the‘Local FITS Conventions’ section in Chapter 4. Since this uses a non-standard FITS convention to encode the long keyword string, programs which use this routine should also call the fits_write_key_longwarn routine to add some COMMENT keywords to warn users of the FITS file that this convention is being used. The fits_write_key_longwarn routine also writes a keyword called LONGSTRN to record the version of the longstring convention that has been used, in case a new convention is adopted at some point in the future. If the LONGSTRN keyword is already present in the header, then fits_write_key_longwarn will simply return without doing anything.

      int fits_write_key_longstr / ffpkls
          (fitsfile *fptr, char *keyname, char *longstr, char *comment,
           > int *status)

      int fits_write_key_longwarn / ffplsw
          (fitsfile *fptr, > int *status)

3
  Write (append) a numbered sequence of keywords into the CHU. The starting index number (nstart) must be greater than 0. One may append the same comment to every keyword (and eliminate the need to have an array of identical comment strings, one for each keyword) by including the ampersand character as the last non-blank character in the (first) COMMENTS string parameter. This same string will then be used for the comment field in all the keywords. One may also enter a null pointer for the comment parameter to leave the comment field of the keyword blank.

      int fits_write_keys_str / ffpkns
          (fitsfile *fptr, char *keyroot, int nstart, int nkeys,
           char **value, char **comment, > int *status)

      int fits_write_keys_[log, lng] / ffpkn[lj]
          (fitsfile *fptr, char *keyroot, int nstart, int nkeys,
           DTYPE *numval, char **comment, int *status)

      int fits_write_keys_[flt, dbl, fixflg, fixdbl] / ffpkne[edfg]
          (fitsfile *fptr, char *keyroot, int nstart, int nkey,
           DTYPE *numval, int decimals, char **comment, > int *status)

4
  Copy an indexed keyword from one HDU to another, modifying the index number of the keyword name in the process. For example, this routine could read the TLMIN3 keyword from the input HDU (by giving keyroot = ‘TLMIN’ and innum = 3) and write it to the output HDU with the keyword name TLMIN4 (by setting outnum = 4). If the input keyword does not exist, then this routine simply returns without indicating an error.

      int fits_copy_key / ffcpky
          (fitsfile *infptr, fitsfile *outfptr, int innum, int outnum,
           char *keyroot, > int *status)

5
  Write (append) a ‘triple precision’ keyword into the CHU in F28.16 format. The floating point keyword value is constructed by concatenating the input integer value with the input double precision fraction value (which must have a value between 0.0 and 1.0). The ffgkyt routine should be used to read this keyword value, because the other keyword reading routines will not preserve the full precision of the value.

      int fits_write_key_triple / ffpkyt
          (fitsfile *fptr, char *keyname, long intval, double frac,
           char *comment, > int *status)

6
  Write keywords to the CHDU that are defined in an ASCII template file. The format of the template file is described under the fits_parse_template routine.

      int fits_write_key_template / ffpktp
          (fitsfile *fptr, const char *filename, > int *status)

### 9.3.4 Insert Keyword Routines

These insert routines are somewhat less efficient than the ‘update’ or ‘write’ keyword routines because the following keywords in the header must be shifted down to make room for the inserted keyword. See Appendix B for the definition of the parameters used in these routines.

1
  Insert a new keyword record into the CHU at the specified position (i.e., immediately preceding the (keynum)th keyword in the header.)

      int fits_insert_record / ffirec
          (fitsfile *fptr, int keynum, char *card, > int *status)

2
  Insert a new keyword into the CHU. The new keyword is inserted immediately following the last keyword that has been read from the header. The ‘longstr’ version has the same functionality as the ‘str’ version except that it also supports the local long string keyword convention for strings longer than 68 characters. A null pointer may be entered for the comment parameter which will cause the comment field to be left blank. The flt, dbl, cmp, and dblcmp versions of this routine have the added feature that if the ’decimals’ parameter is negative, then the ’G’ display format rather then the ’E’ format will be used when constructing the keyword value, taking the absolute value of ’decimals’ for the precision. This will suppress trailing zeros, and will use a fixed format rather than an exponential format, depending on the magnitude of the value.

      int fits_insert_card / ffikey
          (fitsfile *fptr, char *card, > int *status)

      int fits_insert_key_[str, longstr] / ffi[kys, kls]
          (fitsfile *fptr, char *keyname, char *value, char *comment,
           > int *status)

      int fits_insert_key_[log, lng] / ffiky[lj]
          (fitsfile *fptr, char *keyname, DTYPE numval, char *comment,
           > int *status)

      int fits_insert_key_[flt, fixflt, dbl, fixdbl] / ffiky[edfg]
          (fitsfile *fptr, char *keyname, DTYPE numval, int decimals,
           char *comment, > int *status)

      int fits_insert_key_[cmp, dblcmp, fixcmp, fixdblcmp] / ffik[yc,ym,fc,fm]
          (fitsfile *fptr, char *keyname, DTYPE *numval, int decimals,
           char *comment, > int *status)

3
  Insert a new keyword with an undefined, or null, value into the CHU. The value string of the keyword is left blank in this case.

      int fits_insert_key_null / ffikyu
          (fitsfile *fptr, char *keyname, char *comment, > int *status)

### 9.3.5 Read Keyword Routines

Wild card characters may be used when specifying the name of the keyword to be read.

1
  Read a keyword value (with the appropriate data type) and comment from the CHU. If a NULL comment pointer is given on input, then the comment string will not be returned. If the value of the keyword is not defined (i.e., the value field is blank) then an error status = VALUE_UNDEFINED will be returned and the input value will not be changed (except that ffgkys will reset the value to a null string).

      int fits_read_key_str / ffgkys
          (fitsfile *fptr, char *keyname, > char *value, char *comment,
           int *status);

      NOTE: after calling the following routine, programs must explicitly free
            the memory allocated for 'longstr' after it is no longer needed by
            calling fits_free_memory.

      int fits_read_key_longstr / ffgkls
          (fitsfile *fptr, char *keyname, > char **longstr, char *comment,
                 int *status)

      int fits_free_memory / fffree
          (char *longstr, > int *status);

      int fits_read_key_[log, lng, flt, dbl, cmp, dblcmp] / ffgky[ljedcm]
          (fitsfile *fptr, char *keyname, > DTYPE *numval, char *comment,
           int *status)

      int fits_read_key_lnglng / ffgkyjj
          (fitsfile *fptr, char *keyname, > LONGLONG *numval, char *comment,
           int *status)

2
  Read a sequence of indexed keyword values (e.g., NAXIS1, NAXIS2, ...). The input starting index number (nstart) must be greater than 0. If the value of any of the keywords is not defined (i.e., the value field is blank) then an error status = VALUE_UNDEFINED will be returned and the input value for the undefined keyword(s) will not be changed. These routines do not support wild card characters in the root name. If there are no indexed keywords in the header with the input root name then these routines do not return a non-zero status value and instead simply return nfound = 0.

      int fits_read_keys_str / ffgkns
          (fitsfile *fptr, char *keyname, int nstart, int nkeys,
           > char **value, int *nfound,  int *status)

      int fits_read_keys_[log, lng, flt, dbl] / ffgkn[ljed]
          (fitsfile *fptr, char *keyname, int nstart, int nkeys,
           > DTYPE *numval, int *nfound, int *status)

3
  Read the value of a floating point keyword, returning the integer and fractional parts of the value in separate routine arguments. This routine may be used to read any keyword but is especially useful for reading the ’triple precision’ keywords written by ffpkyt.

      int fits_read_key_triple / ffgkyt
          (fitsfile *fptr, char *keyname, > long *intval, double *frac,
           char *comment, int *status)

### 9.3.6 Modify Keyword Routines

These routines modify the value of an existing keyword. An error is returned if the keyword does not exist. Wild card characters may be used when specifying the name of the keyword to be modified. See Appendix B for the definition of the parameters used in these routines.

1
  Modify (overwrite) the nth 80-character header record in the CHU.

      int fits_modify_record / ffmrec
          (fitsfile *fptr, int keynum, char *card, > int *status)

2
  Modify (overwrite) the 80-character header record for the named keyword in the CHU. This can be used to overwrite the name of the keyword as well as its value and comment fields.

      int fits_modify_card / ffmcrd
          (fitsfile *fptr, char *keyname, char *card, > int *status)

5
  Modify the value and comment fields of an existing keyword in the CHU. The ‘longstr’ version has the same functionality as the ‘str’ version except that it also supports the local long string keyword convention for strings longer than 68 characters. Optionally, one may modify only the value field and leave the comment field unchanged by setting the input COMMENT parameter equal to the ampersand character (&) or by entering a null pointer for the comment parameter. The flt, dbl, cmp, and dblcmp versions of this routine have the added feature that if the ’decimals’ parameter is negative, then the ’G’ display format rather then the ’E’ format will be used when constructing the keyword value, taking the absolute value of ’decimals’ for the precision. This will suppress trailing zeros, and will use a fixed format rather than an exponential format, depending on the magnitude of the value.

      int fits_modify_key_[str, longstr] / ffm[kys, kls]
          (fitsfile *fptr, char *keyname, char *value, char *comment,
           > int *status);

      int fits_modify_key_[log, lng] / ffmky[lj]
          (fitsfile *fptr, char *keyname, DTYPE numval, char *comment,
           > int *status)

      int fits_modify_key_[flt, dbl, fixflt, fixdbl] / ffmky[edfg]
          (fitsfile *fptr, char *keyname, DTYPE numval, int decimals,
           char *comment, > int *status)

      int fits_modify_key_[cmp, dblcmp, fixcmp, fixdblcmp] / ffmk[yc,ym,fc,fm]
          (fitsfile *fptr, char *keyname, DTYPE *numval, int decimals,
           char *comment, > int *status)

6
  Modify the value of an existing keyword to be undefined, or null. The value string of the keyword is set to blank. Optionally, one may leave the comment field unchanged by setting the input COMMENT parameter equal to the ampersand character (&) or by entering a null pointer.

      int fits_modify_key_null / ffmkyu
          (fitsfile *fptr, char *keyname, char *comment, > int *status)

### 9.3.7 Update Keyword Routines

1
  These update routines modify the value, and optionally the comment field, of the keyword if it already exists, otherwise the new keyword is appended to the header. A separate routine is provided for each keyword data type. The ‘longstr’ version has the same functionality as the ‘str’ version except that it also supports the local long string keyword convention for strings longer than 68 characters. A null pointer may be entered for the comment parameter which will leave the comment field unchanged or blank. The flt, dbl, cmp, and dblcmp versions of this routine have the added feature that if the ’decimals’ parameter is negative, then the ’G’ display format rather then the ’E’ format will be used when constructing the keyword value, taking the absolute value of ’decimals’ for the precision. This will suppress trailing zeros, and will use a fixed format rather than an exponential format, depending on the magnitude of the value.

      int fits_update_key_[str, longstr] / ffu[kys, kls]
          (fitsfile *fptr, char *keyname, char *value, char *comment,
           > int *status)

      int fits_update_key_[log, lng] / ffuky[lj]
          (fitsfile *fptr, char *keyname, DTYPE numval, char *comment,
           > int *status)

      int fits_update_key_[flt, dbl, fixflt, fixdbl] / ffuky[edfg]
          (fitsfile *fptr, char *keyname, DTYPE numval, int decimals,
           char *comment, > int *status)

      int fits_update_key_[cmp, dblcmp, fixcmp, fixdblcmp] / ffuk[yc,ym,fc,fm]
          (fitsfile *fptr, char *keyname, DTYPE *numval, int decimals,
           char *comment, > int *status)

## 9.4 Define Data Scaling and Undefined Pixel Parameters

These routines set or modify the internal parameters used by CFITSIO to either scale the data or to represent undefined pixels. Generally CFITSIO will scale the data according to the values of the BSCALE and BZERO (or TSCALn and TZEROn) keywords, however these routines may be used to override the keyword values. This may be useful when one wants to read or write the raw unscaled values in the FITS file. Similarly, CFITSIO generally uses the value of the BLANK or TNULLn keyword to signify an undefined pixel, but these routines may be used to override this value. These routines do not create or modify the corresponding header keyword values. See Appendix B for the definition of the parameters used in these routines.

1
  Reset the scaling factors in the primary array or image extension; does not change the BSCALE and BZERO keyword values and only affects the automatic scaling performed when the data elements are written/read to/from the FITS file. When reading from a FITS file the returned data value = (the value given in the FITS array) * BSCALE + BZERO. The inverse formula is used when writing data values to the FITS file.

      int fits_set_bscale / ffpscl
          (fitsfile *fptr, double scale, double zero, > int *status)

2
  Reset the scaling parameters for a table column; does not change the TSCALn or TZEROn keyword values and only affects the automatic scaling performed when the data elements are written/read to/from the FITS file. When reading from a FITS file the returned data value = (the value given in the FITS array) * TSCAL + TZERO. The inverse formula is used when writing data values to the FITS file.

      int fits_set_tscale / fftscl
          (fitsfile *fptr, int colnum, double scale, double zero,
           > int *status)

3
  Define the integer value to be used to signify undefined pixels in the primary array or image extension. This is only used if BITPIX = 8, 16, or 32. This does not create or change the value of the BLANK keyword in the header.

      int fits_set_imgnull / ffpnul
          (fitsfile *fptr, LONGLONG nulval, > int *status)

4
  Define the string to be used to signify undefined pixels in a column in an ASCII table. This does not create or change the value of the TNULLn keyword.

      int fits_set_atblnull / ffsnul
          (fitsfile *fptr, int colnum, char *nulstr, > int *status)

5
  Define the value to be used to signify undefined pixels in an integer column in a binary table (where TFORMn = ’B’, ’I’, or ’J’). This does not create or change the value of the TNULLn keyword.

      int fits_set_btblnull / fftnul
          (fitsfile *fptr, int colnum, LONGLONG nulval, > int *status)

## 9.5 Specialized FITS Primary Array or IMAGE Extension I/O Routines

These routines read or write data values in the primary data array (i.e., the first HDU in the FITS file) or an IMAGE extension. Automatic data type conversion is performed for if the data type of the FITS array (as defined by the BITPIX keyword) differs from the data type of the array in the calling routine. The data values are automatically scaled by the BSCALE and BZERO header values as they are being written or read from the FITS array. Unlike the basic routines described in the previous chapter, most of these routines specifically support the FITS random groups format. See Appendix B for the definition of the parameters used in these routines.

The more primitive reading and writing routines (i. e., ffppr_, ffppn_, ffppn, ffgpv_, or ffgpf_) simply treat the primary array as a long 1-dimensional array of pixels, ignoring the intrinsic dimensionality of the array. When dealing with a 2D image, for example, the application program must calculate the pixel offset in the 1-D array that corresponds to any particular X, Y coordinate in the image. C programmers should note that the ordering of arrays in FITS files, and hence in all the CFITSIO calls, is more similar to the dimensionality of arrays in Fortran rather than C. For instance if a FITS image has NAXIS1 = 100 and NAXIS2 = 50, then a 2-D array just large enough to hold the image should be declared as array[50][100] and not as array[100][50].

For convenience, higher-level routines are also provided to specifically deal with 2D images (ffp2d_ and ffg2d_) and 3D data cubes (ffp3d_ and ffg3d_). The dimensionality of the FITS image is passed by the naxis1, naxis2, and naxis3 parameters and the declared dimensions of the program array are passed in the dim1 and dim2 parameters. Note that the dimensions of the program array may be larger than the dimensions of the FITS array. For example if a FITS image with NAXIS1 = NAXIS2 = 400 is read into a program array which is dimensioned as 512 x 512 pixels, then the image will just fill the lower left corner of the array with pixels in the range 1 - 400 in the X an Y directions. This has the effect of taking a contiguous set of pixel value in the FITS array and writing them to a non-contiguous array in program memory (i.e., there are now some blank pixels around the edge of the image in the program array).

The most general set of routines (ffpss_, ffgsv_, and ffgsf_) may be used to transfer a rectangular subset of the pixels in a FITS N-dimensional image to or from an array which has been declared in the calling program. The fpixel and lpixel parameters are integer arrays which specify the starting and ending pixel coordinate in each dimension (starting with 1, not 0) of the FITS image that is to be read or written. It is important to note that these are the starting and ending pixels in the FITS image, not in the declared array in the program. The array parameter in these routines is treated simply as a large one-dimensional array of the appropriate data type containing the pixel values; The pixel values in the FITS array are read/written from/to this program array in strict sequence without any gaps; it is up to the calling routine to correctly interpret the dimensionality of this array. The two FITS reading routines (ffgsv_ and ffgsf_ ) also have an ‘inc’ parameter which defines the data sampling interval in each dimension of the FITS array. For example, if inc[0]=2 and inc[1]=3 when reading a 2-dimensional FITS image, then only every other pixel in the first dimension and every 3rd pixel in the second dimension will be returned to the ’array’ parameter.

Two types of routines are provided to read the data array which differ in the way undefined pixels are handled. The first type of routines (e.g., ffgpv_) simply return an array of data elements in which undefined pixels are set equal to a value specified by the user in the ‘nulval’ parameter. An additional feature of these routines is that if the user sets nulval = 0, then no checks for undefined pixels will be performed, thus reducing the amount of CPU processing. The second type of routines (e.g., ffgpf_) returns the data element array and, in addition, a char array that indicates whether the value of the corresponding data pixel is undefined (= 1) or defined (= 0). The latter type of routines may be more convenient to use in some circumstances, however, it requires an additional array of logical values which can be unwieldy when working with large data arrays.

1
  Write elements into the FITS data array.

      int fits_write_img / ffppr
          (fitsfile *fptr, int datatype, LONGLONG firstelem, LONGLONG nelements,
           DTYPE *array, int *status);

      int fits_write_img_[byt, sht, usht, int, uint, lng, ulng, lnglng, ulnglng, flt, dbl] /
          ffppr[b,i,ui,k,uk,j,uj,jj,ujj,e,d]
          (fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelements,
           DTYPE *array, > int *status);

      int fits_write_imgnull / ffppn
          (fitsfile *fptr, int datatype, LONGLONG firstelem, LONGLONG nelements,
           DTYPE *array, DTYPE *nulval, > int *status);

      int fits_write_imgnull_[byt, sht, usht, int, uint, lng, ulng, lnglng, ulnglng, flt, dbl] /
          ffppn[b,i,ui,k,uk,j,uj,jj,ujj,e,d]
          (fitsfile *fptr, long group, LONGLONG firstelem,
               LONGLONG nelements, DTYPE *array, DTYPE nulval, > int *status);

2
  Set data array elements as undefined.

      int fits_write_img_null / ffppru
          (fitsfile *fptr, long group, LONGLONG firstelem, LONGLONG nelements,
           > int *status)

3
  Write values into group parameters. This routine only applies to the ‘Random Grouped’ FITS format which has been used for applications in radio interferometry, but is officially deprecated for future use.

      int fits_write_grppar_[byt, sht, usht, int, uint, lng, ulng, lnglng, ulnglng, flt, dbl] /
          ffpgp[b,i,ui,k,uk,j,uj,jj,ujj,e,d]
          (fitsfile *fptr, long group, long firstelem, long nelements,
           > DTYPE *array, int *status)

4
  Write a 2-D or 3-D image into the data array.

      int fits_write_2d_[byt, sht, usht, int, uint, lng, ulng, lnglng, ulnglng, flt, dbl] /
          ffp2d[b,i,ui,k,uk,j,uj,jj,ujj,e,d]
          (fitsfile *fptr, long group, LONGLONG dim1, LONGLONG naxis1,
           LONGLONG naxis2, DTYPE *array, > int *status)

      int fits_write_3d_[byt, sht, usht, int, uint, lng, ulng, lnglng, ulnglng, flt, dbl] /
          ffp3d[b,i,ui,k,uk,j,uj,jj,ujj,e,d]
          (fitsfile *fptr, long group, LONGLONG dim1, LONGLONG dim2, LONGLONG naxis1,
           LONGLONG naxis2, LONGLONG naxis3, DTYPE *array, > int *status)

5
  Write an arbitrary data subsection into the data array.

      int fits_write_subset_[byt, sht, usht, int, uint, lng, ulng, lnglng, ulnglng, flt, dbl] /
          ffpss[b,i,ui,k,uk,j,uj,jj,ujj,e,d]
          (fitsfile *fptr, long group, long naxis, long *naxes,
           long *fpixel, long *lpixel, DTYPE *array, > int *status)

6
  Read elements from the FITS data array.

      int fits_read_img / ffgpv
          (fitsfile *fptr, int  datatype, long firstelem, long nelements,
           DTYPE *nulval, > DTYPE *array, int *anynul, int *status)

      int fits_read_img_[byt, sht, usht, int, uint, lng, ulng, lnglng, ulnglng, flt, dbl] /
          ffgpv[b,i,ui,k,uk,j,uj,jj,ujj,e,d]
          (fitsfile *fptr, long group, long firstelem, long nelements,
           DTYPE nulval, > DTYPE *array, int *anynul, int *status)

      int fits_read_imgnull / ffgpf
          (fitsfile *fptr, int  datatype, long firstelem, long nelements,
           > DTYPE *array, char *nullarray, int *anynul, int *status)

      int  fits_read_imgnull_[byt, sht, usht, int, uint, lng, ulng, lnglng, ulnglng, flt, dbl] /
           ffgpf[b,i,ui,k,uk,j,uj,jj,ujj,e,d]
           (fitsfile *fptr, long group, long firstelem, long nelements,
           > DTYPE *array, char *nullarray, int *anynul, int *status)

7
  Read values from group parameters. This routine only applies to the ‘Random Grouped’ FITS format which has been used for applications in radio interferometry, but is officially deprecated for future use.

      int  fits_read_grppar_[byt, sht, usht, int, uint, lng, ulng, lnglng, ulnglng, flt, dbl] /
           ffggp[b,i,ui,k,uk,j,uj,jj,ujj,e,d]
           (fitsfile *fptr, long group, long firstelem, long nelements,
           > DTYPE *array, int *status)

8
  Read 2-D or 3-D image from the data array. Undefined pixels in the array will be set equal to the value of ’nulval’, unless nulval=0 in which case no testing for undefined pixels will be performed.

      int  fits_read_2d_[byt, sht, usht, int, uint, lng, ulng, lnglng, ulnglng, flt, dbl] /
           ffg2d[b,i,ui,k,uk,j,uj,jj,ujj,e,d]
           (fitsfile *fptr, long group, DTYPE nulval, LONGLONG dim1, LONGLONG naxis1,
           LONGLONG naxis2, > DTYPE *array, int *anynul, int *status)

      int  fits_read_3d_[byt, sht, usht, int, uint, lng, ulng, lnglng, ulnglng, flt, dbl] /
           ffg3d[b,i,ui,k,uk,j,uj,jj,ujj,e,d]
           (fitsfile *fptr, long group, DTYPE nulval, LONGLONG dim1,
           LONGLONG dim2, LONGLONG naxis1, LONGLONG naxis2, LONGLONG naxis3,
           > DTYPE *array, int *anynul, int *status)

9
  Read an arbitrary data subsection from the data array.

      int  fits_read_subset_[byt, sht, usht, int, uint, lng, ulng, lnglng, ulnglng, flt, dbl] /
           ffgsv[b,i,ui,k,uk,j,uj,jj,ujj,e,d]
           (fitsfile *fptr, int group, int naxis, long *naxes,
           long *fpixel, long *lpixel, long *inc, DTYPE nulval,
           > DTYPE *array, int *anynul, int *status)

      int  fits_read_subsetnull_[byt, sht, usht, int, uint, lng, ulng, lnglng, ulnglng, flt, dbl] /
           ffgsf[b,i,ui,k,uk,j,uj,jj,ujj,e,d]
           (fitsfile *fptr, int group, int naxis, long *naxes,
           long *fpixel, long *lpixel, long *inc, > DTYPE *array,
           char *nullarray, int *anynul, int *status)

## 9.6 Specialized FITS ASCII and Binary Table Routines

### 9.6.1 General Column Routines

1
  Get information about an existing ASCII or binary table column. A null pointer may be given for any of the output parameters that are not needed. DATATYPE is a character string which returns the data type of the column as defined by the TFORMn keyword (e.g., ’I’, ’J’,’E’, ’D’, etc.). In the case of an ASCII character column, typecode will have a value of the form ’An’ where ’n’ is an integer expressing the width of the field in characters. For example, if TFORM = ’160A8’ then ffgbcl will return typechar=’A8’ and repeat=20. All the returned parameters are scalar quantities.

      int fits_get_acolparms / ffgacl
        (fitsfile *fptr, int colnum, > char *ttype, long *tbcol,
         char *tunit, char *tform, double *scale, double *zero,
         char *nulstr, char *tdisp, int *status)

      int fits_get_bcolparms / ffgbcl
          (fitsfile *fptr, int colnum, > char *ttype, char *tunit,
           char *typechar, long *repeat, double *scale, double *zero,
           long *nulval, char *tdisp, int  *status)

      int fits_get_bcolparmsll / ffgbclll
          (fitsfile *fptr, int colnum, > char *ttype, char *tunit,
           char *typechar, LONGLONG *repeat, double *scale, double *zero,
           LONGLONG *nulval, char *tdisp, int  *status)

2
  Return optimal number of rows to read or write at one time for maximum I/O efficiency. Refer to the “Optimizing Code” section in Chapter 5 for more discussion on how to use this routine.

      int fits_get_rowsize / ffgrsz
          (fitsfile *fptr, long *nrows, *status)

3
  Define the zero indexed byte offset of the ’heap’ measured from the start of the binary table data. By default the heap is assumed to start immediately following the regular table data, i.e., at location NAXIS1 x NAXIS2. This routine is only relevant for binary tables which contain variable length array columns (with TFORMn = ’Pt’). This routine also automatically writes the value of theap to a keyword in the extension header. This routine must be called after the required keywords have been written (with ffphbn) but before any data is written to the table.

      int fits_write_theap / ffpthp
          (fitsfile *fptr, long theap, > int *status)

4
  Test the contents of the binary table variable array heap, returning the size of the heap, the number of unused bytes that are not currently pointed to by any of the descriptors, and the number of bytes which are pointed to by multiple descriptors. It also returns valid = FALSE if any of the descriptors point to invalid addresses out of range of the heap.

      int fits_test_heap / fftheap
          (fitsfile *fptr, > LONGLONG *heapsize, LONGLONG *unused, LONGLONG *overlap,
           int *validheap, int *status)

5
  Re-pack the vectors in the binary table variable array heap to recover any unused space. Normally, when a vector in a variable length array column is rewritten the previously written array remains in the heap as wasted unused space. This routine will repack the arrays that are still in use, thus eliminating any bytes in the heap that are no longer in use. Note that if several vectors point to the same bytes in the heap, then this routine will make duplicate copies of the bytes for each vector, which will actually expand the size of the heap.

      int fits_compress_heap / ffcmph
          (fitsfile *fptr, > int *status)

### 9.6.2 Low-Level Table Access Routines

The following 2 routines provide low-level access to the data in ASCII or binary tables and are mainly useful as an efficient way to copy all or part of a table from one location to another. These routines simply read or write the specified number of consecutive bytes in an ASCII or binary table, without regard for column boundaries or the row length in the table. These routines do not perform any machine dependent data conversion or byte swapping. See Appendix B for the definition of the parameters used in these routines.

1
  Read or write a consecutive array of bytes from an ASCII or binary table

      int fits_read_tblbytes / ffgtbb
          (fitsfile *fptr, LONGLONG firstrow, LONGLONG firstchar, LONGLONG nchars,
           > unsigned char *values, int *status)

      int fits_write_tblbytes / ffptbb
          (fitsfile *fptr, LONGLONG firstrow, LONGLONG firstchar, LONGLONG nchars,
           unsigned char *values, > int *status)

### 9.6.3 Write Column Data Routines

This subsection describes specialized routines for writing data to FITS tables. Please see section 9.6.4 (“Read Column Data Routines”) for more information about how values are stored in C.

1
  Write elements into an ASCII or binary table column (in the CDU). The data type of the array is implied by the suffix of the routine name.

      int fits_write_col_str / ffpcls
          (fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem,
           LONGLONG nelements, char **array, > int *status)

      int fits_write_col_[log,byt,sht,usht,int,uint,lng,ulng,lnglng,ulnglng,flt,dbl,cmp,dblcmp] /
          ffpcl[l,b,i,ui,k,uk,j,uj,jj,ujj,e,d,c,m]
          (fitsfile *fptr, int colnum, LONGLONG firstrow,
               LONGLONG firstelem, LONGLONG nelements, DTYPE *array, > int *status)

2
  Write elements into an ASCII or binary table column substituting the appropriate FITS null value for any elements that are equal to the nulval parameter.

      int fits_write_colnull_[log, byt, sht, usht, int, uint, lng, ulng, lnglng, ulnglng, flt, dbl] /
          ffpcn[l,b,i,ui,k,uk,j,uj,jj,ujj,e,d]
          (fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem,
           LONGLONG nelements, DTYPE *array, DTYPE nulval, > int *status)

3
  Write string elements into a binary table column (in the CDU) substituting the FITS null value for any elements that are equal to the nulstr string.

      int fits_write_colnull_str / ffpcns
          (fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem,
           LONGLONG nelements, char **array, char *nulstr, > int *status)

4
  Write bit values into a binary byte (’B’) or bit (’X’) table column (in the CDU). Larray is an array of characters corresponding to the sequence of bits to be written. If an element of larray is true (not equal to zero) then the corresponding bit in the FITS table is set to 1, otherwise the bit is set to 0. The ’X’ column in a FITS table is always padded out to a multiple of 8 bits where the bit array starts with the most significant bit of the byte and works down towards the 1’s bit. For example, a ’4X’ array, with the first bit = 1 and the remaining 3 bits = 0 is equivalent to the 8-bit unsigned byte decimal value of 128 (’1000 0000B’). In the case of ’X’ columns, CFITSIO can write to all 8 bits of each byte whether they are formally valid or not. Thus if the column is defined as ’4X’, and one calls ffpclx with firstbit=1 and nbits=8, then all 8 bits will be written into the first byte (as opposed to writing the first 4 bits into the first row and then the next 4 bits into the next row), even though the last 4 bits of each byte are formally not defined and should all be set = 0. It should also be noted that it is more efficient to write ’X’ columns an entire byte at a time, instead of bit by bit. Any of the CFITSIO routines that write to columns (e.g. fits_write_col_byt) may be used for this purpose. These routines will interpret ’X’ columns as though they were ’B’ columns (e.g., ’1X’ through ’8X’ is equivalent to ’1B’, and ’9X’ through ’16X’ is equivalent to ’2B’).

      int fits_write_col_bit / ffpclx
          (fitsfile *fptr, int colnum, LONGLONG firstrow, long firstbit,
           long nbits, char *larray, > int *status)

5
  Write the descriptor for a variable length column in a binary table. This routine can be used in conjunction with ffgdes to enable 2 or more arrays to point to the same storage location to save storage space if the arrays are identical.

        int fits_write_descript / ffpdes
            (fitsfile *fptr, int colnum, LONGLONG rownum, LONGLONG repeat,
             LONGLONG offset, > int *status)

### 9.6.4 Read Column Data Routines

Two types of routines are provided to get the column data which differ in the way undefined pixels are handled. The first set of routines (ffgcv) simply return an array of data elements in which undefined pixels are set equal to a value specified by the user in the ’nullval’ parameter. If nullval = 0, then no checks for undefined pixels will be performed, thus increasing the speed of the program. The second set of routines (ffgcf) returns the data element array and in addition a logical array of flags which defines whether the corresponding data pixel is undefined. See Appendix B for the definition of the parameters used in these routines.

Any column, regardless of it’s intrinsic data type, may be read as a string. It should be noted however that reading a numeric column as a string is 10 - 100 times slower than reading the same column as a number due to the large overhead in constructing the formatted strings. The display format of the returned strings will be determined by the TDISPn keyword, if it exists, otherwise by the data type of the column. The length of the returned strings (not including the null terminating character) can be determined with the fits_get_col_display_width routine. The following TDISPn display formats are currently supported:

        Iw.m   Integer
        Ow.m   Octal integer
        Zw.m   Hexadecimal integer
        Fw.d   Fixed floating point
        Ew.d   Exponential floating point
        Dw.d   Exponential floating point
        Gw.d   General; uses Fw.d if significance not lost, else Ew.d

where w is the width in characters of the displayed values, m is the minimum number of digits displayed, and d is the number of digits to the right of the decimal. The .m field is optional.

1
  Read elements from an ASCII or binary table column (in the CDU). These routines return the values of the table column array elements. The caller is required to allocate the storage `array` before calling. Undefined array elements will be returned with a value = nulval, unless nulval = 0 (or = ’ ’ for ffgcvs) in which case no checking for undefined values will be performed. The anynul parameter is set to true if any of the returned elements are undefined.

  For the `_log` (logical) variant, the C storage type is a `char` single-byte character. A FITS value of ‘`T`’rue reads as 1 and ‘`F`’ reads as 0; other non-FITS characters are preserved untranslated.

  For the `_str` (string) variant the number of elements is the number of strings, and the caller must allocate storage for both the array of pointers `array` and the character array data itself (use `fits_get_col_display_width` or `fits_get_coltype` to determine the number of characters). See section 4.5 (“Dealing with Character Strings”) for more information. Also, when the `_byt` variant is used to read a column stored in the file as string data (TFORMn = ’nA’), the subroutine will read the character bytes (instead of attempting to perform a numerical conversion as other integer variants would do), with no attempt at null termination.

  For the `_cmp` and `_dblcmp` (complex and double complex) variants, `nelements` is the number of numerical pairs; the number of floats or doubles that must be pre-allocated is `2*nelements`.

      int fits_read_col_str / ffgcvs
          (fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem,
           LONGLONG nelements, char *nulstr, > char **array, int *anynul,
           int *status)

      int fits_read_col_[log,byt,sht,usht,int,uint,lng,ulng, lnglng, ulnglng, flt, dbl, cmp, dblcmp] /
          ffgcv[l,b,i,ui,k,uk,j,uj,jj,ujj,e,d,c,m]
          (fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem,
           LONGLONG nelements, DTYPE nulval, > DTYPE *array, int *anynul,
           int *status)

2
  Read elements and null flags from an ASCII or binary table column (in the CHDU). These routines return the values of the table column array elements. Any undefined array elements will have the corresponding nullarray element set equal to TRUE. The anynul parameter is set to true if any of the returned elements are undefined.

      int fits_read_colnull_str / ffgcfs
          (fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem,
           LONGLONG nelements, > char **array, char *nullarray, int *anynul,
           int *status)

      int fits_read_colnull_[log,byt,sht,usht,int,uint,lng,ulng,lnglng,ulnglng,flt,dbl,cmp,dblcmp] /
          ffgcf[l,b,i,ui,k,uk,j,uj,jj,ujj,e,d,c,m]
          (fitsfile *fptr, int colnum, LONGLONG firstrow,
           LONGLONG firstelem, LONGLONG nelements, > DTYPE *array,
           char *nullarray, int *anynul, int *status)

3
  Read an arbitrary data subsection from an N-dimensional array in a binary table vector column. Undefined pixels in the array will be set equal to the value of ’nulval’, unless nulval=0 in which case no testing for undefined pixels will be performed. The first and last rows in the table to be read are specified by fpixel(naxis+1) and lpixel(naxis+1), and hence are treated as the next higher dimension of the FITS N-dimensional array. The INC parameter specifies the sampling interval in each dimension between the data elements that will be returned.

      int fits_read_subset_[byt, sht, usht, int, uint, lng, ulng, lnglng, ulnglng, flt, dbl] /
          ffgsv[b,i,ui,k,uk,j,uj,jj,ull,e,d]
          (fitsfile *fptr, int colnum, int naxis, long *naxes, long *fpixel,
           long *lpixel, long *inc, DTYPE nulval, > DTYPE *array, int *anynul,
           int *status)

4
  Read an arbitrary data subsection from an N-dimensional array in a binary table vector column. Any Undefined pixels in the array will have the corresponding ’nullarray’ element set equal to TRUE. The first and last rows in the table to be read are specified by fpixel(naxis+1) and lpixel(naxis+1), and hence are treated as the next higher dimension of the FITS N-dimensional array. The INC parameter specifies the sampling interval in each dimension between the data elements that will be returned.

      int fits_read_subsetnull_[byt, sht, usht, int, uint, lng, ulng, lnglng, ulnglng, flt, dbl] /
          ffgsf[b,i,ui,k,uk,j,uj,jj,ujj,e,d]
          (fitsfile *fptr, int colnum, int naxis, long *naxes,
           long *fpixel, long *lpixel, long *inc, > DTYPE *array,
           char *nullarray, int *anynul, int *status)

5
  Read bit values from a byte (’B’) or bit (‘X‘) table column (in the CDU). Larray is an array of logical values corresponding to the sequence of bits to be read. If larray is true then the corresponding bit was set to 1, otherwise the bit was set to 0. The ’X’ column in a FITS table is always padded out to a multiple of 8 bits where the bit array starts with the most significant bit of the byte and works down towards the 1’s bit. For example, a ’4X’ array, with the first bit = 1 and the remaining 3 bits = 0 is equivalent to the 8-bit unsigned byte value of 128. Note that in the case of ’X’ columns, CFITSIO can read all 8 bits of each byte whether they are formally valid or not. Thus if the column is defined as ’4X’, and one calls ffgcx with firstbit=1 and nbits=8, then all 8 bits will be read from the first byte (as opposed to reading the first 4 bits from the first row and then the first 4 bits from the next row), even though the last 4 bits of each byte are formally not defined. It should also be noted that it is more efficient to read ’X’ columns an entire byte at a time, instead of bit by bit. Any of the CFITSIO routines that read columns (e.g. fits_read_col_byt) may be used for this purpose. These routines will interpret ’X’ columns as though they were ’B’ columns (e.g., ’8X’ is equivalent to ’1B’, and ’16X’ is equivalent to ’2B’).

      int fits_read_col_bit / ffgcx
          (fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstbit,
           LONGLONG nbits, > char *larray, int *status)

6
  Read any consecutive set of bits from an ’X’ or ’B’ column and interpret them as an unsigned n-bit integer. nbits must be less than 16 or 32 in ffgcxui and ffgcxuk, respectively. If nrows is greater than 1, then the same set of bits will be read from each row, starting with firstrow. The bits are numbered with 1 = the most significant bit of the first element of the column.

      int fits_read_col_bit_[usht, uint] / ffgcx[ui,uk]
          (fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG, nrows,
           long firstbit, long nbits, > DTYPE *array, int *status)

7
  Return the descriptor for a variable length column in a binary table. The descriptor consists of 2 integer parameters: the number of elements in the array and the starting offset relative to the start of the heap. The first pair of routine returns a single descriptor whereas the second pair of routine returns the descriptors for a range of rows in the table. The only difference between the 2 routines in each pair is that one returns the parameters as ’long’ integers, whereas the other returns the values as 64-bit ’LONGLONG’ integers.

      int fits_read_descript / ffgdes
          (fitsfile *fptr, int colnum, LONGLONG rownum, > long *repeat,
               long *offset, int *status)

      int fits_read_descriptll / ffgdesll
          (fitsfile *fptr, int colnum, LONGLONG rownum, > LONGLONG *repeat,
               LONGLONG *offset, int *status)

      int fits_read_descripts / ffgdess
          (fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG nrows
           > long *repeat, long *offset, int *status)

      int fits_read_descriptsll / ffgdessll
          (fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG nrows
           > LONGLONG *repeat, LONGLONG *offset, int *status)