# Chapter 2  Creating the CFITSIO Library

## 2.1 Building the Library

The CFITSIO code is contained in about 40 C source files (*.c) and header files (*.h). On VAX/VMS systems 2 assembly-code files (vmsieeed.mar and vmsieeer.mar) are also needed.

CFITSIO is written in ANCI C and should be compatible with most existing C and C++ compilers. Cray supercomputers are currently not supported.

### 2.1.1 Unix Systems

The CFITSIO library is built on Unix systems by typing:

     >  ./configure [--prefix=/target/installation/path] [--enable-reentrant]
                    [--enable-sse2] [--enable-ssse3]
     >  make
     >  make install  (this step is optional)

at the operating system prompt. The configure command customizes the Makefile for the particular system, then the ‘make’ command compiles the source files and builds the library. Type ‘./configure’ and not simply ‘configure’ to ensure that the configure script in the current directory is run and not some other system-wide configure script. The optional ’prefix’ argument to configure gives the path to the directory where the CFITSIO library and include files should be installed via the later ’make install’ command. For example,

       > ./configure --prefix=/usr1/local

will cause the ’make install’ command to copy the CFITSIO libcfitsio file to /usr1/local/lib and the necessary include files to /usr1/local/include (assuming of course that the process has permission to write to these directories).

All the available configure options can be seen by entering the command

       > ./configure --help

Some of the more useful options are described below:

The –enable-reentrant option will attempt to configure CFITSIO so that it can be used in multi-threaded programs. See the "Using CFITSIO in Multi-threaded Environments" section, below, for more details.

The –enable-sse2 and –enable-ssse3 options will cause configure to attempt to build CFITSIO using faster byte-swapping algorithms. See the "Optimizing Programs" chapter of this manual for more information about these options.

The –with-gsiftp-flavour and –with-gsiftp options enable support for the Globus Toolkit gsiftp protocal. See the "Extended File Name Syntax" chapter for more information.

The –with-bzip2 option enables support for reading FITS files that have been externally compressed by the bzip2 algorithm. This requires that the CFITSIO library, and all applications program that use CFITSIO, to be linked to include the libbz2 library.

By default, both static and shared (dynamic) versions of the CFITSIO library are built. To build only a static library, pass `--disable-shared` to configure; to build only a shared library, pass `--disable-static`. When using the shared library the executable code is not copied into your program at link time and instead the program locates the necessary library code at run time, normally through LD_LIBRARY_PATH or some other method. The advantages of using a shared library are:

       1.  Less disk space if you build more than 1 program
       2.  Less memory if more than one copy of a program using the shared
           library is running at the same time since the system is smart
           enough to share copies of the shared library at run time.
       3.  Possibly easier maintenance since a new version of the shared
           library can be installed without relinking all the software
           that uses it (as long as the subroutine names and calling
           sequences remain unchanged).
       4.  No run-time penalty.

The disadvantages are:

       1. More hassle at runtime.  You have to either build the programs
          specially or have LD_LIBRARY_PATH set right.
       2. There may be a slight start up penalty, depending on where you are
          reading the shared library and the program from and if your CPU is
          either really slow or really heavily loaded.

On Mac OS X platforms, a .dylib file will be created instead of .so. If installed in a nonstandard location, add its location to the DYLD_LIBRARY_PATH environment variable so that the library can be found at run time.

On HP/UX systems, the environment variable CFLAGS should be set to -Ae before running configure to enable "extended ANSI" features.

By default, a set of Fortran-callable wrapper routines are also built and included in the CFITSIO library if a Fortran compiler is detected by configure. If no Fortran compiler is found, the wrapper routines are omitted automatically.

It may not be possible to statically link programs that use CFITSIO on some platforms (namely, on Solaris 2.6) due to the network drivers (which provide FTP and HTTP access to FITS files). It is possible to make both a dynamic and a static version of the CFITSIO library, but network file access will not be possible using the static version.

### 2.1.2 VMS

On VAX/VMS and ALPHA/VMS systems the make_gfloat.com command file may be executed to build the cfitsio.olb object library using the default G-floating point option for double variables. The make_dfloat.com and make_ieee.com files may be used instead to build the library with the other floating point options. Note that the getcwd function that is used in the group.c module may require that programs using CFITSIO be linked with the ALPHA$LIBRARY:VAXCRTL.OLB library. See the example link line in the next section of this document.

### 2.1.3 Windows PCs

A precompiled DLL version of CFITSIO (not necessarily the latest version) is available on the CFITSIO web site. The CFITSIO library may also be built from the source code using the CMake build system. See the "README.win" file in the CFITSIO source distribution for more information.

### 2.1.4 Macintosh PCs

When building on Mac OS-X, users should follow the Unix instructions, above. See the README.MacOS file for instructions on building a Universal Binary that supports both Intel and PowerPC CPUs.

## 2.2 Testing the Library

The CFITSIO library should be tested by building and running the testprog.c program that is included with the release. On Unix systems, type:

        % make testprog
        % testprog > testprog.lis
        % diff testprog.lis testprog.out
        % cmp testprog.fit testprog.std

On VMS systems, (assuming cc is the name of the C compiler command), type:

        $ cc testprog.c
        $ link testprog, cfitsio/lib, alpha$library:vaxcrtl/lib
        $ run testprog

The test program should produce a FITS file called ‘testprog.fit’ that is identical to the ‘testprog.std’ FITS file included with this release. The diagnostic messages (which were redirected to the file testprog.lis in the Unix example) should be identical to the listing contained in the file testprog.out. The ’diff’ and ’cmp’ commands shown above should not report any differences in the files. (There may be some minor format differences, such as the presence or absence of leading zeros, or 3 digit exponents in numbers, which can be ignored).

The Fortran wrappers in CFITSIO may be tested with the testf77 program on Unix systems with:

        % gfortran -o testf77 testf77.f -L. -lcfitsio -lz -lcurl
        % testf77 > testf77.lis
        % diff testf77.lis testf77.out
        % cmp testf77.fit testf77.std

On machines running SUN O/S, Fortran programs must be compiled with the ’-f’ option to force double precision variables to be aligned on 8-byte boundarys to make the fortran-declared variables compatible with C. A similar compiler option may be required on other platforms. Failing to use this option may cause the program to crash on FITSIO routines that read or write double precision variables.

Also note that on some systems, the output listing of the testf77 program may differ slightly from the testf77.std template, if leading zeros are not printed by default before the decimal point when using F format.

A few other utility programs are included with CFITSIO; the first four of these programs can be compiled and linked by typing ‘make program_name’ where ‘program_name’ is the actual name of the program:

        speed - measures the maximum throughput (in MB per second)
                  for writing and reading FITS files with CFITSIO.

        listhead - lists all the header keywords in any FITS file

        fitscopy - copies any FITS file (especially useful in conjunction
                     with the CFITSIO's extended input filename syntax).

        cookbook - a sample program that performs common read and
                     write operations on a FITS file.

        iter_a, iter_b, iter_c - examples of the CFITSIO iterator routine

## 2.3 Linking Programs with CFITSIO

When linking applications software with the CFITSIO library, several system libraries usually need to be specified on the link command line. On Unix systems, the most reliable way to determine what libraries are required is to type ’make testprog’ and see what libraries the configure script has added. The typical libraries that need to be added are -lm (the math library) and -lnsl and -lsocket (needed only for FTP and HTTP file access). These latter 2 libraries are not needed on VMS and Windows platforms, because FTP file access is not currently supported on those platforms.

Note that when upgrading to a newer version of CFITSIO it is usually necessary to recompile, as well as relink, the programs that use CFITSIO, because the definitions in fitsio.h often change.

## 2.4 Using CFITSIO in Multi-threaded Environments

CFITSIO can be used either with the POSIX pthreads interface or the OpenMP interface for multi-threaded parallel programs. When used in a multi-threaded environment, the CFITSIO library *must* be built using the -D_REENTRANT compiler directive. This can be done using the following build commands:

      >./configure --enable-reentrant
      > make

A function called fits_is_reentrant is available to test whether or not CFITSIO was compiled with the -D_REENTRANT directive. When this feature is enabled, multiple threads can call any of the CFITSIO routines to simultaneously read or write separate FITS files. Multiple threads can also read data from the same FITS file simultaneously, as long as the file was opened independently by each thread. This relies on the operating system to correctly deal with reading the same file by multiple processes. Different threads should not share the same ’fitsfile’ pointer to read an opened FITS file, unless locks are placed around the calls to the CFITSIO reading routines. Different threads should never try to write to the same FITS file.

## 2.5 Getting Started with CFITSIO

In order to effectively use the CFITSIO library it is recommended that new users begin by reading the “CFITSIO Quick Start Guide”. It contains all the basic information needed to write programs that perform most types of operations on FITS files. The set of example FITS utility programs that are available from the CFITSIO web site are also very useful for learning how to use CFITSIO. To learn even more about the capabilities of the CFITSIO library the following steps are recommended:

1. Read the following short ‘FITS Primer’ chapter for an overview of the structure of FITS files.

2. Review the Programming Guidelines in Chapter 4 to become familiar with the conventions used by the CFITSIO interface.

3. Refer to the cookbook.c, listhead.c, and fitscopy.c programs that are included with this release for examples of routines that perform various common FITS file operations. Type ’make program_name’ to compile and link these programs on Unix systems.

4. Write a simple program to read or write a FITS file using the Basic Interface routines described in Chapter 5.

5. Scan through the more specialized routines that are described in the following chapters to become familiar with the functionality that they provide.

## 2.6 Example Program

The following listing shows an example of how to use the CFITSIO routines in a C program. Refer to the cookbook.c program that is included with the CFITSIO distribution for other example routines.

This program creates a new FITS file, containing a FITS image. An ‘EXPOSURE’ keyword is written to the header, then the image data are written to the FITS file before closing the FITS file.

    #include "fitsio.h"  /* required by every program that uses CFITSIO  */
    main()
    {
        fitsfile *fptr;       /* pointer to the FITS file; defined in fitsio.h */
        int status, ii, jj;
        long  fpixel = 1, naxis = 2, nelements, exposure;
        long naxes[2] = { 300, 200 };   /* image is 300 pixels wide by 200 rows */
        short array[200][300];

        status = 0;         /* initialize status before calling fitsio routines */
        fits_create_file(&fptr, "testfile.fits", &status);   /* create new file */

        /* Create the primary array image (16-bit short integer pixels */
        fits_create_img(fptr, SHORT_IMG, naxis, naxes, &status);

        /* Write a keyword; must pass the ADDRESS of the value */
        exposure = 1500.;
        fits_update_key(fptr, TLONG, "EXPOSURE", &exposure,
             "Total Exposure Time", &status);

        /* Initialize the values in the image with a linear ramp function */
        for (jj = 0; jj < naxes[1]; jj++)
            for (ii = 0; ii < naxes[0]; ii++)
                array[jj][ii] = ii + jj;

        nelements = naxes[0] * naxes[1];          /* number of pixels to write */

        /* Write the array of integers to the image */
        fits_write_img(fptr, TSHORT, fpixel, nelements, array[0], &status);

        fits_close_file(fptr, &status);            /* close the file */

        fits_report_error(stderr, status);  /* print out any error messages */
        return( status );
    }