C----------------------------------------------------------------------
        subroutine ftcopy(iunit,ounit,moreky,status)

C       copies the CHDU from IUNIT to the CHDU of OUNIT.
C       This will also reserve space in the header for MOREKY keywords
C       if MOREKY > 0.

C       iunit   i  fortran unit number of the input file to be copied
C       ounit   i  fortran unit number of the output file to be copied to
C       moreky  i  create space in header for this many more keywords
C       status  i  output error status
C
C       written by Wm Pence, HEASARC/GSFC, Jan, 1992

        integer iunit,ounit,moreky,status

C       COMMON BLOCK DEFINITIONS:--------------------------------------------
        integer nb,ne
        parameter (nb = 12)
        parameter (ne = 128)
        integer bufnum,bufpnt,reclen,recnum,bytnum
        integer chdu,maxhdu,hdstrt,hdend,nxthdr,dtstrt
        logical wrmode,modify
        real compid
        common/ft0001/bufnum(199),bufpnt(nb),reclen(199),recnum(nb),
     &  bytnum(nb),wrmode(nb),modify(nb),chdu(nb),maxhdu(nb),
     &  hdstrt(nb,ne),hdend(nb),nxthdr(nb),dtstrt(nb),compid
        character cbuff*2880, hrec*80, xdummy*2800
        common/ftheap/cbuff,hrec,xdummy

C       END OF COMMON BLOCK DEFINITIONS-----------------------------------

        integer ibuff,obuff,nblock,i,xtend,nkeys,nadd
        integer bitpix,naxis,naxes(99),pcount,gcount
        logical simple,extend

        if (status .gt. 0)return

        ibuff=bufnum(iunit)
        obuff=bufnum(ounit)

C       find out the number of keywords which exist in the input CHDU
        call ftghsp(iunit,nkeys,nadd,status)

C       copy the keywords one at a time to the output CHDU
        if ( (chdu(ibuff) .eq. 1 .and. chdu(obuff) .ne. 1) .or.
     &     (chdu(ibuff) .ne. 1 .and. chdu(obuff) .eq. 1) )then
C               copy primary array to image extension, or vise versa

C               copy the required keywords:
                simple=.true.
                extend=.true.
                call ftghpr(iunit,99,simple,bitpix,naxis,
     &          naxes,pcount,gcount,extend,status)
                if (status .gt. 0)return
                call ftphpr(ounit,simple,bitpix,naxis,
     &          naxes,pcount,gcount,extend,status)
                if (status .gt. 0)return

C               copy remaining keywords, excluding pcount, gcount and extend
                do 10 i=naxis+4,nkeys
                    call ftgrec(iunit,i,hrec,status)
                    if (hrec(1:8) .ne. 'PCOUNT  ' .and.
     &                  hrec(1:8) .ne. 'GCOUNT  ' .and.
     &                  hrec(1:8) .ne. 'EXTEND  ')then
                           call ftprec(ounit,hrec,status)
                    end if
10              continue
        else 
C               just copy all the keys exactly from the input file to the output
                do 20 i=1,nkeys
                    call ftgrec(iunit,i,hrec,status)
                    call ftprec(ounit,hrec,status)
20              continue
        end if
  
C       reserve space for more keywords (if moreky > 0)
        call fthdef(ounit,moreky,status)

C       close the header by padding it with blanks and writing the END record
        call ftchdu(ounit,status)

C       Calculate the number of bytes to be copied.  By definition there
C       will be an integral number of 2880-byte logical blocks to be copied
        nblock=(hdstrt(ibuff,chdu(ibuff)+1)-dtstrt(ibuff))/2880

        if (nblock .gt. 0)then
C           move to the beginning of the data in the input and output files
            call ftmbyt(iunit,dtstrt(ibuff),.false.,status)
            call ftmbyt(ounit,dtstrt(obuff),.true.,status)

C           now copy the data one block at a time
            do 30 i=1,nblock
                call ftgcbf(iunit,0,2880,cbuff,status)
                call ftpcbf(ounit,0,2880,cbuff,status)
30          continue
        end if

C       now initialize the parameters describing the output CHDU:
C       move back to the beginning of the output extension 
        call ftmbyt(ounit,hdstrt(obuff,chdu(obuff)),.false.,status)

        if (status .gt. 0)return

C       the location of the END record is currently unknown, so 
C       temporarily just set it to a very large number
        hdend(obuff)=1000000000

C       read the various header keywords to determine the structure of the CHDU
        call ftrhdu(ounit,xtend,status)
        end
