module cfitsio_interfaces
  use cfitsio_messaging
  !---------------------------------------------------------------------
  ! Fortran interfaces to the CFITSIO library. Use module 'cfitsio_api'
  ! in your programs.
  !---------------------------------------------------------------------
  !
  interface
    subroutine ftvers(version)
    !-------------------------------------------------------------------
    !  Return the current version number of the fitsio library. The
    ! version number will be incremented with each new release of
    ! CFITSIO.
    !-------------------------------------------------------------------
    real(kind=4), intent(out) :: version
    end subroutine ftvers
    !
    subroutine ftopen(iunit,name,rwmode,block,status)
    !-------------------------------------------------------------------
    ! Open an existing FITS file with readonly or read/write access
    !-------------------------------------------------------------------
    integer(kind=4),  intent(in)    :: iunit   ! Fortran I/O unit number
    character(len=*), intent(in)    :: name    ! Name of file to be opened
    integer(kind=4)                 :: rwmode  ! File access mode: 0 = readonly; else = read and write
    integer(kind=4),  intent(out)   :: block   ! Returned record length blocking factor
    integer(kind=4),  intent(inout) :: status  ! Returned error status (0=ok)
    end subroutine ftopen
    !
    subroutine ftinit(iunit,filename,blocksize,status)
    !-------------------------------------------------------------------
    ! Close a FITS file that was previously opened with ftopen or ftinit
    !------------------------------------------ -------------------------
    integer(kind=4),  intent(in)    :: iunit      ! Fortran I/O unit number
    character(len=*), intent(in)    :: filename   ! Name of file to be initialized
    integer(kind=4),  intent(in)    :: blocksize  ! Block size (ignored?)
    integer(kind=4),  intent(inout) :: status     ! Returned error status (0=ok)
    end subroutine ftinit
    !
    subroutine ftclos(iunit,status)
    !-------------------------------------------------------------------
    ! Close a FITS file that was previously opened with ftopen or ftinit
    !-------------------------------------------------------------------
    integer(kind=4), intent(in)    :: iunit   ! Fortran I/O unit number
    integer(kind=4), intent(inout) :: status  ! Returned error status (0=ok)
    end subroutine ftclos
    !
    subroutine ftrprt(stream,status)
    !-------------------------------------------------------------------
    ! Display the error status message and flush the error stack
    !-------------------------------------------------------------------
    character(len=*), intent(in) :: stream  ! 'STDOUT' or 'STDERR'
    integer(kind=4),  intent(in) :: status  ! Error status
    end subroutine ftrprt
    !
    subroutine ftcmsg
    !-------------------------------------------------------------------
    ! Clear the error message stack
    !-------------------------------------------------------------------
    end subroutine ftcmsg
    !
    subroutine ftgerr(status,errtext)
    !-------------------------------------------------------------------
    !  Return the descriptive text string corresponding to a FITSIO
    ! error status code. The 30-character length string contains a brief
    ! description of the cause of the error.
    !-------------------------------------------------------------------
    integer(kind=4),  intent(in)  :: status
    character(len=*), intent(out) :: errtext
    end subroutine ftgerr
    !
    subroutine ftflus(iunit,status)
    !-------------------------------------------------------------------
    ! Flush internal buffers of data to the output FITS file previously
    ! opened with ftopen or ftinit.
    !-------------------------------------------------------------------
    integer(kind=4), intent(in)    :: iunit   ! Fortran I/O unit number
    integer(kind=4), intent(inout) :: status  ! Returned error status (0=ok)
    end subroutine ftflus
    !
    subroutine ftphps(iunit,bitpix,naxis,naxes,status)
    !-------------------------------------------------------------------
    ! Put the primary header or IMAGE extension keywords into the CHU.
    !-------------------------------------------------------------------
    integer(kind=4), intent(in)    :: iunit         ! Fortran I/O unit number
    integer(kind=4), intent(in)    :: bitpix        ! Number of bits per value
    integer(kind=4), intent(in)    :: naxis         ! Number of dimensions
    integer(kind=4), intent(in)    :: naxes(naxis)  ! Dimensions
    integer(kind=4), intent(inout) :: status        ! Returned error status (0=ok)
    end subroutine ftphps
    !
    subroutine ftthdu(iunit,nhdu,status)
    !-------------------------------------------------------------------
    ! Return the total number of HDUs in the FITS file. The CHDU
    ! remains unchanged.
    !-------------------------------------------------------------------
    integer(kind=4), intent(in)    :: iunit   ! Fortran I/O unit number
    integer(kind=4), intent(out)   :: nhdu    !
    integer(kind=4), intent(inout) :: status  ! Returned error status (0=ok)
    end subroutine ftthdu
    !
    subroutine ftgkyd(iunit,keywrd,dval,comm,status)
    !-------------------------------------------------------------------
    ! Read a double precision value and comment string from a header
    ! record
    !-------------------------------------------------------------------
    integer(kind=4),  intent(in)    :: iunit   ! Fortran I/O unit number
    character(len=*), intent(in)    :: keywrd  ! Keyword name
    real(kind=8),     intent(out)   :: dval    ! Output keyword value
    character(len=*), intent(out)   :: comm    ! Output keyword comment
    integer(kind=4),  intent(inout) :: status  ! Returned error status (0=ok)
    end subroutine ftgkyd
    !
    subroutine ftgkyj(iunit,keywrd,intval,comm,status)
    !-------------------------------------------------------------------
    ! Read an integer value and the comment string from a header record
    !-------------------------------------------------------------------
    integer(kind=4),  intent(in)    :: iunit   ! Fortran I/O unit number
    character(len=*), intent(in)    :: keywrd  ! Keyword name
    integer(kind=4),  intent(out)   :: intval  ! Output keyword value
    character(len=*), intent(out)   :: comm    ! Output keyword comment
    integer(kind=4),  intent(inout) :: status  ! Returned error status (0=ok)
    end subroutine ftgkyj
    !
    subroutine ftgkyl(iunit,keywrd,logval,comm,status)
    !-------------------------------------------------------------------
    ! Read a logical value and the comment string from a header record
    !-------------------------------------------------------------------
    integer(kind=4),  intent(in)    :: iunit   ! Fortran I/O unit number
    character(len=*), intent(in)    :: keywrd  ! Keyword name
    logical,          intent(out)   :: logval  ! Output keyword value
    character(len=*), intent(out)   :: comm    ! Output keyword comment
    integer(kind=4),  intent(inout) :: status  ! Returned error status (0=ok)
    end subroutine ftgkyl
    !
    subroutine ftgkys(iunit,keywrd,strval,comm,status)
    !-------------------------------------------------------------------
    ! Read a character string value and comment string from a header
    ! record
    !-------------------------------------------------------------------
    integer(kind=4),  intent(in)    :: iunit   ! Fortran I/O unit number
    character(len=*), intent(in)    :: keywrd  ! Keyword name
    character(len=*), intent(out)   :: strval  ! Output keyword value
    character(len=*), intent(out)   :: comm    ! Output keyword comment
    integer(kind=4),  intent(inout) :: status  ! Returned error status (0=ok)
    end subroutine ftgkys
    !
    subroutine ftmahd(iunit,extno,xtend,status)
    !-------------------------------------------------------------------
    ! Move to Absolute Header Data unit
    ! Move the i/o pointer to the specified HDU and initialize all the
    ! common block parameters which describe the extension
    !-------------------------------------------------------------------
    integer(kind=4), intent(in)    :: iunit   ! Fortran I/O unit number
    integer(kind=4), intent(in)    :: extno   ! Number of the extension to point to
    integer(kind=4), intent(out)   :: xtend   ! Returned type of extension
    integer(kind=4), intent(inout) :: status  ! Returned error status (0=ok)
    end subroutine ftmahd
    !
    subroutine ftmnhd(iunit,hdutype,extname,extver,status)
    !-------------------------------------------------------------------
    ! Move to the (first) HDU which has the specified extension type and
    ! EXTNAME (or HDUNAME) and EXTVER keyword values. The hdutype
    ! parameter may have a value of IMAGE_HDU (0), ASCII_TBL (1),
    ! BINARY_TBL (2), or ANY_HDU (-1) where ANY_HDU means that only the
    ! extname and extver values will be used to locate the correct
    ! extension. If the input value of extver is 0 then the EXTVER
    ! keyword is ignored and the first HDU with a matching EXTNAME (or
    ! HDUNAME) keyword will be found. If no matching HDU is found in the
    ! file then the current HDU will remain unchanged and a status =
    ! BAD_HDU_NUM (301) will be returned.
    !-------------------------------------------------------------------
    integer(kind=4),  intent(in)    :: iunit    ! Fortran I/O unit number
    integer(kind=4),  intent(in)    :: hdutype  !
    character(len=*), intent(in)    :: extname  !
    integer(kind=4),  intent(in)    :: extver   !
    integer(kind=4),  intent(inout) :: status   ! Returned error status (0=ok)
    end subroutine ftmnhd
    !
    subroutine ftgcno(iunit,casesn,templt,colnum,status)
    !-------------------------------------------------------------------
    ! Determine the column number corresponding to an input column name.
    ! This supports the * and ? wild cards in the input template.
    !-------------------------------------------------------------------
    integer(kind=4),  intent(in)    :: iunit   ! Fortran i/o unit number
    logical,          intent(in)    :: casesn  ! .true. if an exact case match of the names is required
    character(len=*), intent(in)    :: templt  ! Name of column as specified in a TTYPE keyword
    integer(kind=4),  intent(out)   :: colnum  ! Number of the column (first column = 1, a value of 0 is returned if the column is not found)
    integer(kind=4),  intent(inout) :: status  ! Returned error status
    end subroutine ftgcno
    !
    subroutine ftgcfe(iunit,colnum,frow,felem,nelem,array,flgval,anynul,status)
    !-------------------------------------------------------------------
    ! Read an array of R*4 values from a specified column of the table.
    ! Any undefined pixels will be have the corresponding value of FLGVAL
    ! set equal to .true., and ANYNUL will be set equal to .true. if any
    ! pixels are undefined.
    !-------------------------------------------------------------------
    integer(kind=4), intent(in)    :: iunit      ! Fortran i/o unit number
    integer(kind=4), intent(in)    :: colnum     ! Number of the column to read
    integer(kind=4), intent(in)    :: frow       ! First row to read
    integer(kind=4), intent(in)    :: felem      ! First element within the row to read
    integer(kind=4), intent(in)    :: nelem      ! Number of elements to read
    real(kind=4),    intent(out)   :: array(*)   ! Returned array of data values that was read from FITS file
    logical,         intent(out)   :: flgval(*)  ! Set to .true. if corresponding element undefined
    logical,         intent(inout) :: anynul     ! Set to .true. if any of the returned values are undefined
    integer(kind=4), intent(inout) :: status     ! Returned error status
    end subroutine ftgcfe
    !
    subroutine ftgcfd(iunit,colnum,frow,felem,nelem,array,flgval,anynul,status)
    !-------------------------------------------------------------------
    ! Read an array of R*8 values from a specified column of the table.
    ! Any undefined pixels will be have the corresponding value of FLGVAL
    ! set equal to .true., and ANYNUL will be set equal to .true. if any
    ! pixels are undefined.
    !-------------------------------------------------------------------
    integer(kind=4), intent(in)    :: iunit      ! Fortran i/o unit number
    integer(kind=4), intent(in)    :: colnum     ! Number of the column to read
    integer(kind=4), intent(in)    :: frow       ! First row to read
    integer(kind=4), intent(in)    :: felem      ! First element within the row to read
    integer(kind=4), intent(in)    :: nelem      ! Number of elements to read
    real(kind=8),    intent(out)   :: array(*)   ! Returned array of data values that was read from FITS file
    logical,         intent(out)   :: flgval(*)  ! Set to .true. if corresponding element undefined
    logical,         intent(inout) :: anynul     ! Set to .true. if any of the returned values are undefined
    integer(kind=4), intent(inout) :: status     ! Returned error status
    end subroutine ftgcfd
    !
    subroutine ftgcfj(iunit,colnum,frow,felem,nelem,array,flgval,anynul,status)
    !-------------------------------------------------------------------
    ! Read an array of I*4 values from a specified column of the table.
    ! Any undefined pixels will be have the corresponding value of FLGVAL
    ! set equal to .true., and ANYNUL will be set equal to .true. if any
    ! pixels are undefined.
    !-------------------------------------------------------------------
    integer(kind=4), intent(in)    :: iunit      ! Fortran i/o unit number
    integer(kind=4), intent(in)    :: colnum     ! Number of the column to read
    integer(kind=4), intent(in)    :: frow       ! First row to read
    integer(kind=4), intent(in)    :: felem      ! First element within the row to read
    integer(kind=4), intent(in)    :: nelem      ! Number of elements to read
    integer(kind=4), intent(out)   :: array(*)   ! Returned array of data values that was read from FITS file
    logical,         intent(out)   :: flgval(*)  ! Set to .true. if corresponding element undefined
    logical,         intent(inout) :: anynul     ! Set to .true. if any of the returned values are undefined
    integer(kind=4), intent(inout) :: status     ! Returned error status
    end subroutine ftgcfj
    !
    subroutine ftgcfs(iunit,colnum,frow,felem,nelem,array,flgval,anynul,status)
    !-------------------------------------------------------------------
    ! Read an array of character strings from a specified column of the table.
    ! Any undefined pixels will be have the corresponding value of FLGVAL
    ! set equal to .true., and ANYNUL will be set equal to .true. if any
    ! pixels are undefined.
    !-------------------------------------------------------------------
    integer(kind=4),  intent(in)    :: iunit      ! Fortran i/o unit number
    integer(kind=4),  intent(in)    :: colnum     ! Number of the column to read
    integer(kind=4),  intent(in)    :: frow       ! First row to read
    integer(kind=4),  intent(in)    :: felem      ! First element within the row to read
    integer(kind=4),  intent(in)    :: nelem      ! Number of elements to read
    character(len=*), intent(out)   :: array(*)   ! Returned array of data values that was read from FITS file
    logical,          intent(out)   :: flgval(*)  ! Set to .true. if corresponding element undefined
    logical,          intent(inout) :: anynul     ! Set to .true. if any of the returned values are undefined
    integer(kind=4),  intent(inout) :: status     ! Returned error status
    end subroutine ftgcfs
    !
    subroutine ftgcfl(iunit,colnum,frow,felem,nelem,array,flgval,anynul,status)
    !-------------------------------------------------------------------
    ! Read an array of logical values from a specified column of the table.
    ! Any undefined pixels will be have the corresponding value of FLGVAL
    ! set equal to .true., and ANYNUL will be set equal to .true. if any
    ! pixels are undefined.
    !-------------------------------------------------------------------
    integer(kind=4), intent(in)    :: iunit      ! Fortran i/o unit number
    integer(kind=4), intent(in)    :: colnum     ! Number of the column to read
    integer(kind=4), intent(in)    :: frow       ! First row to read
    integer(kind=4), intent(in)    :: felem      ! First element within the row to read
    integer(kind=4), intent(in)    :: nelem      ! Number of elements to read
    logical,         intent(out)   :: array(*)   ! Returned array of data values that was read from FITS file
    logical,         intent(out)   :: flgval(*)  ! Set to .true. if corresponding element undefined
    logical,         intent(inout) :: anynul     ! Set to .true. if any of the returned values are undefined
    integer(kind=4), intent(inout) :: status     ! Returned error status
    end subroutine ftgcfl
    !
    subroutine ftgcvd(iunit,colnum,frow,felem,nelem,nulval,array,anynul,status)
    !-------------------------------------------------------------------
    ! Read an array of real*8 values from a specified column of the table.
    ! Any undefined pixels will be set equal to the value of NULVAL,
    ! unless NULVAL=0, in which case no checks for undefined pixels will
    ! be made.
    !-------------------------------------------------------------------
    integer(kind=4), intent(in)    :: iunit     ! Fortran i/o unit number
    integer(kind=4), intent(in)    :: colnum    ! Number of the column to read
    integer(kind=4), intent(in)    :: frow      ! First row to read
    integer(kind=4), intent(in)    :: felem     ! First element within the row to read
    integer(kind=4), intent(in)    :: nelem     ! Number of elements to read
    real(kind=8),    intent(in)    :: nulval    ! Value that undefined pixels will be set to
    real(kind=8),    intent(out)   :: array(*)  ! Returned array of data values that was read from FITS file
    logical,         intent(inout) :: anynul    ! Set to .true. if any of the returned values are undefined
    integer(kind=4), intent(inout) :: status    ! Returned error status
    end subroutine ftgcvd
    !
    subroutine ftgcve(iunit,colnum,frow,felem,nelem,nulval,array,anynul,status)
    !-------------------------------------------------------------------
    ! Read an array of real*4 values from a specified column of the table.
    ! Any undefined pixels will be set equal to the value of NULVAL,
    ! unless NULVAL=0, in which case no checks for undefined pixels will
    ! be made.
    !-------------------------------------------------------------------
    integer(kind=4), intent(in)    :: iunit     ! Fortran i/o unit number
    integer(kind=4), intent(in)    :: colnum    ! Number of the column to read
    integer(kind=4), intent(in)    :: frow      ! First row to read
    integer(kind=4), intent(in)    :: felem     ! First element within the row to read
    integer(kind=4), intent(in)    :: nelem     ! Number of elements to read
    real(kind=4),    intent(in)    :: nulval    ! Value that undefined pixels will be set to
    real(kind=4),    intent(out)   :: array(*)  ! Returned array of data values that was read from FITS file
    logical,         intent(inout) :: anynul    ! Set to .true. if any of the returned values are undefined
    integer(kind=4), intent(inout) :: status    ! Returned error status
    end subroutine ftgcve
    !
    subroutine ftgcvj(iunit,colnum,frow,felem,nelem,nulval,array,anynul,status)
    !-------------------------------------------------------------------
    ! Read an array of integer*4 values from a specified column of the table.
    ! Any undefined pixels will be set equal to the value of NULVAL,
    ! unless NULVAL=0, in which case no checks for undefined pixels will
    ! be made.
    !-------------------------------------------------------------------
    integer(kind=4), intent(in)    :: iunit     ! Fortran i/o unit number
    integer(kind=4), intent(in)    :: colnum    ! Number of the column to read
    integer(kind=4), intent(in)    :: frow      ! First row to read
    integer(kind=4), intent(in)    :: felem     ! First element within the row to read
    integer(kind=4), intent(in)    :: nelem     ! Number of elements to read
    integer(kind=4), intent(in)    :: nulval    ! Value that undefined pixels will be set to
    integer(kind=4), intent(out)   :: array(*)  ! Returned array of data values that was read from FITS file
    logical,         intent(inout) :: anynul    ! Set to .true. if any of the returned values are undefined
    integer(kind=4), intent(inout) :: status    ! Returned error status
    end subroutine ftgcvj
    !
    subroutine ftgcvs(iunit,colnum,frow,felem,nelem,nulval,array,anynul,status)
    !-------------------------------------------------------------------
    ! Read an array of character strings from a specified column of the table.
    ! Any undefined pixels will be set equal to the value of NULVAL,
    ! unless NULVAL=0, in which case no checks for undefined pixels will
    ! be made.
    !-------------------------------------------------------------------
    integer(kind=4),  intent(in)    :: iunit     ! Fortran i/o unit number
    integer(kind=4),  intent(in)    :: colnum    ! Number of the column to read
    integer(kind=4),  intent(in)    :: frow      ! First row to read
    integer(kind=4),  intent(in)    :: felem     ! First element within the row to read
    integer(kind=4),  intent(in)    :: nelem     ! Number of elements to read
    character(len=*), intent(in)    :: nulval    ! Value that undefined pixels will be set to
    character(len=*), intent(out)   :: array(*)  ! Returned array of data values that was read from FITS file
    logical,          intent(inout) :: anynul    ! Set to .true. if any of the returned values are undefined
    integer(kind=4),  intent(inout) :: status    ! Returned error status
    end subroutine ftgcvs
    !
    subroutine ftgcl(iunit,colnum,frow,felem,nelem,array,status)
    !-------------------------------------------------------------------
    ! Read an array of logical values from a specified column of the table.
    ! Any undefined pixels will be set equal to the value of NULVAL,
    ! unless NULVAL=0, in which case no checks for undefined pixels will
    ! be made.
    !-------------------------------------------------------------------
    integer(kind=4),  intent(in)    :: iunit     ! Fortran i/o unit number
    integer(kind=4),  intent(in)    :: colnum    ! Number of the column to read
    integer(kind=4),  intent(in)    :: frow      ! First row to read
    integer(kind=4),  intent(in)    :: felem     ! First element within the row to read
    integer(kind=4),  intent(in)    :: nelem     ! Number of elements to read
    logical,          intent(out)   :: array(*)  ! Returned array of data values that was read from FITS file
    integer(kind=4),  intent(inout) :: status    ! Returned error status
    end subroutine ftgcl
    !
    subroutine ftghps(iunit,keysexist,key_no,status)
    !-------------------------------------------------------------------
    ! Return the number of keywords in the header and the current
    ! position in the header. This returns the number of the keyword
    ! record that will be read next (or one greater than the position of
    ! the last keyword that was read or written). A value of 1 is
    ! returned if the pointer is positioned at the beginning of the
    ! header.
    !-------------------------------------------------------------------
    integer(kind=4), intent(in)    :: iunit      ! Fortran I/O unit number
    integer(kind=4), intent(out)   :: keysexist  ! Number of available keys
    integer(kind=4), intent(out)   :: key_no     ! Next key to read
    integer(kind=4), intent(inout) :: status     ! Returned error status
    end subroutine ftghps
    !
    subroutine ftgkyn(iunit,key_no,keyword,value,comment,status)
    !-------------------------------------------------------------------
    ! Get the name, value (as a string), and comment of the nth keyword
    ! in CHU. This routine also checks that the returned keyword name
    ! (KEYWORD) contains only legal ASCII characters. Call FTGREC and
    ! FTPSVC to bypass this error check.
    !-------------------------------------------------------------------
    integer(kind=4),  intent(in)    :: iunit    ! Fortran I/O unit number
    integer(kind=4),  intent(in)    :: key_no   ! The key number
    character(len=*), intent(out)   :: keyword  !
    character(len=*), intent(out)   :: value    !
    character(len=*), intent(out)   :: comment  !
    integer(kind=4),  intent(inout) :: status   ! Returned error status
    end subroutine ftgkyn
    !
    subroutine ftukys(iunit,keywrd,strval,comm,status)
    !-------------------------------------------------------------------
    ! Update the value and comment fields of a keyword in the CHU.
    !-------------------------------------------------------------------
    integer(kind=4),  intent(in)    :: iunit   ! Fortran I/O unit number
    character(len=*), intent(in)    :: keywrd  ! Keyword name
    character(len=*), intent(in)    :: strval  ! Keyword value
    character(len=*), intent(in)    :: comm    ! Keyword comment
    integer(kind=4),  intent(inout) :: status  ! Returned error status (0=ok)
    end subroutine ftukys
    !
    subroutine ftukyj(iunit,keywrd,intval,comm,status)
    !-------------------------------------------------------------------
    ! Update the value and comment fields of a keyword in the CHU.
    !-------------------------------------------------------------------
    integer(kind=4),  intent(in)    :: iunit   ! Fortran I/O unit number
    character(len=*), intent(in)    :: keywrd  ! Keyword name
    integer(kind=4),  intent(in)    :: intval  ! Keyword value
    character(len=*), intent(in)    :: comm    ! Keyword comment
    integer(kind=4),  intent(inout) :: status  ! Returned error status (0=ok)
    end subroutine ftukyj
    !
    subroutine ftgsfe(iunit,group,naxis,naxes,fpixels,lpixels,incs, &
                      array,flagvals,anyf,status)
    !-------------------------------------------------------------------
    ! Get an arbitrary data subsection from the data array. Any
    ! Undefined pixels in the array will have the corresponding
    ! 'flagvals' element set equal to .TRUE.
    !-------------------------------------------------------------------
    integer(kind=4),  intent(in)    :: iunit        ! Fortran I/O unit number
    integer(kind=4),  intent(in)    :: group        !
    integer(kind=4),  intent(in)    :: naxis        ! Number of axes
    integer(kind=4),  intent(in)    :: naxes(*)     ! Axes length
    integer(kind=4),  intent(in)    :: fpixels(*)   ! BLC
    integer(kind=4),  intent(in)    :: lpixels(*)   ! TRC
    integer(kind=4),  intent(in)    :: incs(*)      ! Step in each dimension
    real(kind=4),     intent(out)   :: array(*)     ! Data array to read
    logical,          intent(out)   :: flagvals(*)  ! NULL flag for each value
    logical,          intent(out)   :: anyf         ! At least one NULL value?
    integer(kind=4),  intent(inout) :: status     ! Returned error status (0=ok)
    end subroutine ftgsfe
    !
    subroutine ftppre(iunit,group,fpixel,nelements,values,status)
    !-------------------------------------------------------------------
    ! Put elements into the data array
    !-------------------------------------------------------------------
    integer(kind=4),  intent(in)    :: iunit      ! Fortran I/O unit number
    integer(kind=4),  intent(in)    :: group      !
    integer(kind=4),  intent(in)    :: fpixel     ! Position within the 1-D array of the first pixel to write
    integer(kind=4),  intent(in)    :: nelements  ! Number of elements to write
    real(kind=4),     intent(in)    :: values(*)  ! Data array to write
    integer(kind=4),  intent(inout) :: status     ! Returned error status (0=ok)
    end subroutine ftppre
    !
    subroutine ftpsse(iunit,group,naxis,naxes,fpixels,lpixels,array,status)
    !-------------------------------------------------------------------
    ! Put an arbitrary data subsection into the data array
    !-------------------------------------------------------------------
    integer(kind=4),  intent(in)    :: iunit      ! Fortran I/O unit number
    integer(kind=4),  intent(in)    :: group      !
    integer(kind=4),  intent(in)    :: naxis      ! Number of axes
    integer(kind=4),  intent(in)    :: naxes(*)   ! Axes length
    integer(kind=4),  intent(in)    :: fpixels(*) ! BLC
    integer(kind=4),  intent(in)    :: lpixels(*) ! TRC
    real(kind=4),     intent(in)    :: array(*)   ! Data array to write
    integer(kind=4),  intent(inout) :: status     ! Returned error status (0=ok)
    end subroutine ftpsse
    !
    function fits_read_col_flt(fptr,colnum,firstrow,firstelem,nelem,  &
                               nulval,array,anynul,status)  &
             bind(c,name='ffgcve')
    use, intrinsic :: iso_c_binding, only : c_float,c_int,c_long_long,c_ptr
    !-------------------------------------------------------------------
    ! Get elements from an ASCII or binary table column (in the CDU).
    ! These routines return the values of the table column array
    ! elements. Undefined array elements will be returned with a value =
    ! nullval, unless nullval = 0 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.
    ! ---
    ! C interface to the CFITSIO routine FFGCVE (modern name
    ! fits_read_col_flt). This routine accepts c_long_long (I*8 values)
    ! while FTGCVE or FTGCVELL (Fortran API) accept only I*4 for nelem.
    !-------------------------------------------------------------------
    integer(c_int) :: fits_read_col_flt  ! Function value on return
    type(c_ptr),          value         :: fptr
    integer(c_int),       value         :: colnum
    integer(c_long_long), value         :: firstrow
    integer(c_long_long), value         :: firstelem
    integer(c_long_long), value         :: nelem
    real(c_float),        value         :: nulval
    real(c_float),        intent(out)   :: array(*)
    integer(c_int),       intent(inout) :: anynul
    integer(c_int),       intent(inout) :: status
    end function fits_read_col_flt
    !
    function cunit2fits(unit) bind(c,name='CUnit2FITS') result(fptr)
    use, intrinsic :: iso_c_binding, only : c_int,c_ptr
    !-------------------------------------------------------------------
    ! Convert a Fortran CFITSIO unit number into the corresponding
    ! C 'fitsfile*' pointer for mixed-language calls.
    !-------------------------------------------------------------------
    integer(c_int), value :: unit
    type(c_ptr) :: fptr
    end function cunit2fits
    !
  end interface
  !
contains
  !
  subroutine cfitsio_file_cptr(unit,cptr,error)
    use, intrinsic :: iso_c_binding, only : c_associated,c_int,c_null_ptr,c_ptr
    !---------------------------------------------------------------------
    ! Return the C 'fitsfile*' pointer associated with a Fortran CFITSIO
    ! unit number and flag whether the conversion failed.
    !---------------------------------------------------------------------
    integer(kind=4), intent(in)    :: unit
    type(c_ptr),     intent(out)   :: cptr
    logical,         intent(inout) :: error
    !
    cptr = cunit2fits(int(unit,kind=c_int))
    if (.not.c_associated(cptr)) then
      write(*,'(a)') 'E-CFITSIO,  Error while converting Fortran FITS unit to C fitsfile pointer'
      error = .true.
      cptr = c_null_ptr
      return
    endif
  end subroutine cfitsio_file_cptr
  !
end module cfitsio_interfaces
