!
! Binary real conversion routines
!
subroutine ieee32_to_real(ieee32,ni,map,ndata,nfill,bscal,bzero,bval)
  use gildas_def
  !---------------------------------------------------------------------
  ! @ no-interface
  ! Convert 4-bytes floating point numbers to native format (single
  ! precision).
  !
  ! Endianness vs IEEE-754, what's the status?
  ! - "[In FITS format,] the individual data values shall be stored in
  !   big-endian byte order". Note that x86 CPUs are little-endian.
  ! - "Transmission of 32- and 64-bit floating-point data within the
  !   FITS format shall use the ANSI/IEEE-754 standard". Note that
  !   IEEE-754 does not enforce endianness.
  !
  ! Both rules combined mean that, in FITS, floating points are stored
  ! using big-endian. Note that Gildas refers to IEEE for little-endian
  ! machines, and to EEEI to big-endian. Don't be confused: IEEE-754 is
  ! just a standard which defines how to describe floating points, it
  ! does not describe endianness.
  !
  ! Reference:
  !   "Definition of the Flexible Image Transport System"
  !    Version 3.0: approved 2008 July 10 by the IAUFWG
  !    Document publication date: 2010 November 18
  !---------------------------------------------------------------------
  integer(kind=4),           intent(in)    :: ieee32(*)   ! Input buffer in IEEE format
  integer(kind=size_length), intent(in)    :: ni          ! Buffer size
  integer(kind=size_length), intent(in)    :: ndata       ! Output array size
  real(kind=4),              intent(out)   :: map(ndata)  ! Output array
  integer(kind=size_length), intent(inout) :: nfill       ! Counter in output array
  real(kind=4),              intent(in)    :: bscal       ! Scaling factor
  real(kind=4),              intent(in)    :: bzero       ! Offset
  real(kind=4),              intent(in)    :: bval        ! Blanking value
  ! Local
  integer(kind=size_length) :: n
  !
  n = min(ndata-nfill,ni)
#if defined(VAX)
  call setblnk4(bval)
  call eir4va_sl(ieee32,map(nfill+1),n)
  call rsetblnk
#endif
#if defined(IEEE)
  call eir4ie_sl(ieee32,map(nfill+1),n)
#endif
#if defined(EEEI)
  map(nfill+1:nfill+n) = ieee32(1:n)
#endif
  !
  ! Scaling is poor style for floats, but not strictly forbidden...
  if (bzero.ne.0.0 .or. bscal.ne.1.0) then
    map(nfill+1:nfill+n) = map(nfill+1:nfill+n)*bscal+bzero
  endif
  nfill = nfill+n
end subroutine ieee32_to_real
!
subroutine real_to_ieee32 (ieee32,ni,map,ndata,nfill,bval,eval)
  use gildas_def
  !---------------------------------------------------------------------
  ! @ no-interface obsolete
  !  Blanking values are NOT correctly translated to a NaN in present
  ! version. This must be fixed before floating FITS can be routinely
  ! written!!!
  ! => Obsolete! Use instead 'real_to_real4' which translates correctly
  ! blanks into NaNs
  !---------------------------------------------------------------------
  real(kind=4),              intent(out)   :: ieee32(*)   ! Output buffer in IEEE format
  integer(kind=size_length), intent(in)    :: ni          ! Buffer size
  integer(kind=size_length), intent(in)    :: ndata       ! Input array size
  real(kind=4),              intent(in)    :: map(ndata)  ! Input array
  integer(kind=size_length), intent(inout) :: nfill       ! Counter in output array
  real(kind=4),              intent(in)    :: bval        ! Blanking value
  real(kind=4),              intent(in)    :: eval        ! Blanking tolerance
  ! Local
  integer(kind=size_length) :: n
  !
  n = min(ndata-nfill,ni)
#if defined(VAX)
  call setblnk4(bval)
  call var4ei_sl(map(nfill+1),ieee32,n)
  call rsetblnk
#endif
#if defined(IEEE)
  call ier4ei_sl(map(nfill+1),ieee32,n)
#endif
#if defined(EEEI)
  ieee32(1:n) = map(nfill+1:nfill+n) 
#endif
  nfill = nfill+n
end subroutine real_to_ieee32
!
subroutine ieee64_to_dble (ieee64,ni,map,ndata,nfill,bscal,bzero,bval)
  use gildas_def
  !---------------------------------------------------------------------
  ! @ private
  ! Convert 8-bytes floating point numbers to native format (double
  ! precision).
  !---------------------------------------------------------------------
  real(kind=8),              intent(in)    :: ieee64(*)   ! Input buffer in IEEE format
  integer(kind=size_length), intent(in)    :: ni          ! Buffer size
  integer(kind=size_length), intent(in)    :: ndata       ! Output array size
  real(kind=8),              intent(out)   :: map(ndata)  ! Output array
  integer(kind=size_length), intent(inout) :: nfill       ! Counter in output array
  real(kind=8),              intent(in)    :: bscal       ! Scaling factor
  real(kind=8),              intent(in)    :: bzero       ! Offset
  real(kind=8),              intent(in)    :: bval        ! Blanking value
  ! Local
  integer(kind=size_length) :: n
  !
  n = min(ndata-nfill,ni)
#if defined(VAX)
  call setblnk8(bval)
  call eir8va_sl(ieee64,map(nfill+1),n)
  call rsetblnk
#endif
#if defined(IEEE)
  call eir8ie_sl(ieee64,map(nfill+1),n)
#endif
#if defined(EEEI)
  map(nfill+1:nfill+n) = ieee64(1:n)
#endif
  !
  ! Scaling is poor style for floats, but not strictly forbidden...
  if (bzero.ne.0.0 .or. bscal.ne.1.0) then
    map(nfill+1:nfill+n) = map(nfill+1:nfill+n) * bscal + bzero 
  endif
  nfill = nfill+n
end subroutine ieee64_to_dble
!
subroutine dble_to_ieee64 (ieee64,ni,map,ndata,nfill,bval,eval)
  use gildas_def
  !---------------------------------------------------------------------
  ! @ private
  ! Blanking values are NOT correctly translated to a NaN in present
  ! version. This must be fixed before floating FITS can be routinely
  ! written!!!
  !---------------------------------------------------------------------
  real(kind=8),              intent(out)   :: ieee64(*)   ! Output buffer in IEEE format
  integer(kind=size_length), intent(in)    :: ni          ! Buffer size
  integer(kind=size_length), intent(in)    :: ndata       ! Input array size
  real(kind=8),              intent(in)    :: map(ndata)  ! Input array
  integer(kind=size_length), intent(inout) :: nfill       ! Counter in output array
  real(kind=8),              intent(in)    :: bval        ! Blanking value
  real(kind=8),              intent(in)    :: eval        ! Blanking tolerance
  ! Local
  integer(kind=size_length) :: n
  !
  n = min(ndata-nfill,ni)
#if defined(VAX)
  call setblnk8(bval)
  call var8ei_sl(map(nfill+1),ieee64,n)
  call rsetblnk
#endif
#if defined(IEEE)
  call ier8ei_sl(map(nfill+1),ieee64,n)
#endif
#if defined(EEEI)
  ieee64(1:n) = map(nfill+1:nfill+n)
#endif
  nfill = nfill+n
end subroutine dble_to_ieee64
!
subroutine ieee64_to_real(ieee64,ni,map,ndata,nfill,bscal,bzero,bval)
  use gildas_def
  !---------------------------------------------------------------------
  ! @ no-interface
  ! Convert 8-bytes floating point numbers to native format (single
  ! precision).
  !---------------------------------------------------------------------
  integer(kind=size_length), intent(in)    :: ni          ! Buffer size
  real(kind=8),              intent(inout) :: ieee64(ni)  ! Input buffer in IEEE format, modified...
  integer(kind=size_length), intent(in)    :: ndata       ! Output array size
  real(kind=4),              intent(out)   :: map(ndata)  ! Output array
  integer(kind=size_length), intent(inout) :: nfill       ! Counter in output array
  real(kind=4),              intent(in)    :: bscal       ! Scaling factor
  real(kind=4),              intent(in)    :: bzero       ! Offset
  real(kind=4),              intent(in)    :: bval        ! Blanking value
  ! Local
  integer(kind=size_length) :: n
  !
  n = min(ndata-nfill,ni)
  !
  ! Convert the REAL*8 array into an automatic array
#if defined(VAX) 
  call setblnk8(bval)
  call eir8va_sl(ieee64,ieee64,n)
  call rsetblnk
#elif defined(IEEE)
  call eir8ie_sl(ieee64,ieee64,n)
#endif
  ! Copy converted doubles to single precision output array
  ! Scaling is poor style for floats, but not strictly forbidden...
  if (bscal.eq.1.0 .and. bzero.eq.0.0) then
    map(nfill+1:nfill+n) = ieee64(1:n)
  else
    map(nfill+1:nfill+n) = ieee64(1:n)*bscal + bzero
  endif
  nfill = nfill+n
end subroutine ieee64_to_real
