function gio_riox (lun,ibl,buf,size)
  use gildas_def
  !---------------------------------------------------------------------
  ! @ private
  !       Read one direct acess block
  !       The file must have been opened with the appropriate block size
  !---------------------------------------------------------------------
  integer(kind=4) :: gio_riox  !
  integer(kind=4),             intent(in)  :: lun        ! Logical unit number
  integer(kind=record_length), intent(in)  :: ibl        ! Block number
  integer(kind=4),             intent(in)  :: size       ! Block size
  integer(kind=4),             intent(out) :: buf(size)  ! Buffer to be read
  read (unit=lun,rec=ibl,iostat=gio_riox) buf
end function gio_riox
!
function gio_wiox (lun,ibl,buf,size)
  use gildas_def
  !---------------------------------------------------------------------
  ! @ private
  !       Write one direct acess block
  !       The file must have been opened with the appropriate block size
  !---------------------------------------------------------------------
  integer(kind=4) :: gio_wiox  !
  integer(kind=4),             intent(in) :: lun        ! Logical unit number
  integer(kind=record_length), intent(in) :: ibl        ! Block number
  integer(kind=4),             intent(in) :: size       ! Block size
  integer(kind=4),             intent(in) :: buf(size)  ! Buffer to be read
  write (unit=lun,rec=ibl,iostat=gio_wiox) buf
end function gio_wiox
!
subroutine gdf_fill(n,x,v)
  use gildas_def
  !---------------------------------------------------------------------
  ! @ no-interface (because of argument type mismatch)
  !       Fill array with value
  !---------------------------------------------------------------------
  integer(kind=size_length), intent(in)  :: n  ! Number of elements
  integer(kind=4), intent(out) :: x(n)         ! Data array
  integer(kind=4), intent(in)  :: v            ! Filling value
  ! Local
  integer(kind=size_length) :: i
  do i=1,n
    x(i) = v
  enddo
end subroutine gdf_fill
!
subroutine gdf_index_to_where(inone,ndim,dims,iwhere)
  use gildas_def
  !---------------------------------------------------------------------
  ! @ public
  ! GDF Convert a (rank-1) position in a pixel number for arbitrary dimensions
  ! Will need an INTERFACE from outside
  !---------------------------------------------------------------------
  integer(kind=8), intent(in)  :: inone         ! Relative position in rank-1 array
  integer(kind=4), intent(in)  :: ndim          ! Number of dimensions
  integer(kind=index_length), intent(in)  :: dims(ndim)    ! Number of dimensions
  integer(kind=index_length), intent(out) :: iwhere(ndim)  ! Pixel position
  !
  integer(kind=8) :: tdim(ndim)
  integer(kind=8) :: jnone, jsize
  integer :: i, j, k
  !
  tdim = max(1,dims)
  !
  jnone = inone-1
  do i=ndim,2,-1
    jsize = 1
    do j=1,i-1
      jsize = jsize*tdim(j)
    enddo
    k = jnone / jsize
    jnone = jnone - k*jsize
    iwhere(i) = k+1
  enddo
  iwhere(1) = jnone+1
  !! Print *,'GDF_INDEX_TO_WHERE ',inone,' = ',iwhere
end subroutine gdf_index_to_where
!
subroutine gdf_where_to_index(inone,ndim,dims,iwhere)
  use gildas_def
  !---------------------------------------------------------------------
  ! @ public
  ! GDF Convert a pixel number in a (rank-1) position for arbitrary dimensions
  ! Will need an INTERFACE from outside
  !---------------------------------------------------------------------
  integer(kind=8), intent(out) :: inone         ! Relative position in rank-1 array
  integer(kind=4), intent(in)  :: ndim          ! Number of dimensions
  integer(kind=index_length), intent(in)  :: dims(ndim)    ! Number of dimensions
  integer(kind=index_length), intent(in)  :: iwhere(ndim)  ! Pixel position
  !
  integer(kind=8) :: tdim(ndim)
  integer(kind=8) :: jnone, step
  integer i
  !
  tdim = max(1,dims)
  !
  jnone = iwhere(1)
  step = tdim(1)
  do i=2,ndim
    jnone = jnone +  (iwhere(i)-1)*step
    step = step*tdim(i)
  enddo
  inone = jnone
  !! Print *,'GDF_WHERE_TO_INDEX ',inone,' = ',iwhere
end subroutine gdf_where_to_index
!
subroutine gio_form (inform,ouform)
  use gbl_format
  !---------------------------------------------------------------------
  ! @ private
  !       Determine machine dependent data format from image
  !       data format
  !---------------------------------------------------------------------
  integer(kind=4), intent(in) :: inform                 ! Input Format
  integer(kind=4), intent(out) :: ouform                ! Output Format
  ! Local
  integer :: forms(9),if
  data forms/fmt_r4,fmt_r8,fmt_i4,fmt_l,fmt_i2,fmt_by,fmt_c4,fmt_c8,fmt_i8/
  !
  if (inform.eq.0 .or. inform.eq.6) then
    ouform = inform
  else
    if = mod(-inform,10)       ! From 1 to 9
    ouform = forms(if)         ! Output format
  endif
end subroutine gio_form
!
function gio_block (form,size)
  use gildas_def
  use gio_params
  use gbl_format
  !---------------------------------------------------------------------
  ! @ private
  !       Compute number of blocks from image size
  !---------------------------------------------------------------------
  integer(kind=record_length) :: gio_block  !
  integer(kind=4),           intent(in) :: form  ! Input format
  integer(kind=size_length), intent(in) :: size  ! Array  size
  !
  if (form.eq.fmt_r8.or.form.eq.fmt_c4.or.form.eq.fmt_i8) then
    gio_block = (size+63)/64
  elseif (form.eq.fmt_by) then
    gio_block = (size+511)/512
  elseif (form.eq.fmt_c8) then
    gio_block = (size+31)/32
  elseif (form.lt.0) then
    gio_block = (size+127)/128
  else
    gio_block = 0
  endif
end function gio_block
!
subroutine gdf_style (is,gtype)
  use gio_image
  !---------------------------------------------------------------------
  ! @ private
  !       Returns image type
  !---------------------------------------------------------------------
  integer(kind=4), intent(in) :: is             ! Image Slot
  character(len=*), intent(out) :: gtype        ! Image type
  !
  if (islot(is).eq.code_gio_empty) then
    gtype = ' '
  else
    gtype = gheads(is)%char%type
  endif
end subroutine gdf_style
!
subroutine gio_idim (is,size)
  use gio_params
  use gio_image
  !---------------------------------------------------------------------
  ! @ private
  !  Define image dimensions and compute image size
  !---------------------------------------------------------------------
  integer(kind=4),           intent(in)  :: is    ! Image Slot
  integer(kind=size_length), intent(out) :: size  ! Array  size
  ! Local
  integer(kind=4) :: i
  !
  indim(is)   = gheads(is)%gil%ndim
  idims(:,is) = gheads(is)%gil%dim(:)
  do i=gdf_maxdims,2,-1
    if (idims(i,is).eq.0) then
      idims(i,is) = 1
      indim(is)   = min(indim(is),i-1)
    endif
  enddo
  !
  size = 1
  do i=1,gdf_maxdims
    size = size*idims(i,is)
  enddo
end subroutine gio_idim
!
subroutine gdf_dims(is,ndim,dims)
  use gildas_def
  use gio_image
  !---------------------------------------------------------------------
  ! @ public
  ! GDF  API routine
  !             Return image dimensions (for SIC, in fact)
  ! The output dimensions are kind=index_length
  !---------------------------------------------------------------------
  integer(kind=4), intent(in) :: is                  ! Image slot
  integer(kind=4), intent(out) :: ndim               ! Number of dimensions
  integer(kind=index_length), intent(out) :: dims(:) ! Dimensions
  !
  integer i
  !
  ndim = indim(is)
  do i=1,gdf_maxdims
     dims(i) = idims(i,is)
  enddo
end subroutine gdf_dims
!
subroutine convgcod (sycode,imcode,conver,mess,isev)
  use gio_interfaces, only : gdf_conversion
  use gio_convert
  use gbl_message
  !---------------------------------------------------------------------
  ! @ private
  !       SYCODE system code
  !       '-'    IEEE
  !       '.'    EEEI (IBM like)
  !       '_'    VAX
  !       IMCODE file code
  !       '<'    IEEE  64 bits    (Little Endian, 99.9 % of recent computers)
  !       '>'    EEEI  64 bits    (Big Endian, HPUX, IBM-RISC, and SPARC ...)
  !---------------------------------------------------------------------
  character(len=1), intent(in) :: sycode        !  System code
  character(len=1), intent(inout) :: imcode     !  File code
  integer, intent(out)  :: conver               !  Conversion code number
  character(len=*), intent(out) :: mess         !  Message trailer
  integer, intent(out)  :: isev                 !  Severity of message (D or I)
  ! Local
  character(len=16) :: conversion
  logical is64bit
  !
  conver = unknown
  if (imcode.eq.'<') then
    is64bit = .true.
    imcode = '-'
  else if (imcode.eq.'>') then
    is64bit = .true.
    imcode = '.'
  else
    is64bit = .false.
  endif
  isev = seve%i
  !
  if (imcode.eq.sycode) then
    conver = 0
    isev = seve%d
    ! print *,'No conversion'
  elseif (imcode.eq.'_') then
    if (sycode.eq.'-') then
      conver = vax_to_ieee     ! (VAX to DEC)
    elseif (sycode.eq.'.') then
      conver = vax_to_eeei     ! (VAX to IBM)
    endif
  elseif (imcode.eq.'-') then
    if (sycode.eq.'_') then
      conver = ieee_to_vax     ! (DEC to VAX)
    elseif (sycode.eq.'.') then
      conver = ieee_to_eeei    ! (DEC to IBM)
    endif
  elseif (imcode.eq.'.') then
    if (sycode.eq.'_') then
      conver = eeei_to_vax     ! (IBM to VAX)
    elseif (sycode.eq.'-') then
      conver = eeei_to_ieee    ! (IBM to DEC)
      ! print *,'IBM to DEC ',conver,' EEEI_TO_IEEE'
    endif
  endif
  if (conver.gt.mconve) conver  = unknown
  call gdf_conversion(conver,conversion)
  if (is64bit) then
     mess = 'File is '//trim(conversion)//', Header Version 2 (64 bit) '
     conver = conver+off_64bit
  else
     mess = 'File is '//conversion//', Header Version 1 (32 bit)'
     isev = seve%i
  endif
end subroutine convgcod
!
function gio_rih (is,gtype,form,lndb)
  use gio_interfaces, except_this=>gio_rih
  use gildas_def
  use gio_image
  use gio_convert
  use gio_headers
  use gbl_message
  !---------------------------------------------------------------------
  ! @ private
  ! GDF / GIO  Internal routine
  !       Read full header from internal buffer, with format conversion
  !     GIO_RIH / GIO_WIH / GIO_EIH are the only routine addressing
  !             the data format of the header
  !---------------------------------------------------------------------
  integer(kind=4) :: gio_rih  !
  integer(kind=4),             intent(in)  :: is     ! Image Slot
  character(len=*),            intent(out) :: gtype  ! Image type
  integer(kind=4),             intent(out) :: form   ! Data format
  integer(kind=record_length), intent(out) :: lndb   ! Number of 512 byte blocks
  ! Global
  external :: iei4ei,eii4ie
  external :: ier8va,ier4va, var8ie,var4ie
  external :: ier8ei,ier4ei, eir8ie,eir4ie
  external :: var8ei,var4ei, eir8va,eir4va
  external :: r8tor8,r4tor4, i4toi4,i8toi8
  ! Local
  character(len=*), parameter :: rname = 'GIO_RIH'
  integer(kind=record_length) :: js
  integer(kind=4) :: ier, len64, isev
  character(len=12) :: gdftit
  character(len=1) :: sycode
  character(len=128) :: chain
  logical error
  integer(kind=4) :: abuf32(128)
  type(gildas_header_v2) :: hd64
  type(gildas_header_v1) :: hd32
  integer(kind=4) :: indb
  integer(kind=8) :: jndb
  integer(kind=4) :: jconv, lc
  !
  call bytoch (gdfbuf,gdftit,12)
  !
  error = .false.
  gio_rih = 0
  if (gdftit(1:6).ne.'GILDAS') return
  call gio_syscod (sycode)
  call convgcod (sycode,gdftit(7:7),iconv(is),chain,isev)
  if (iconv(is).lt.0) return
  !
  call gildas_null(gheads(is))
  !
  ! File to Memory
  !
  gtype = gdftit
  gtype(7:7) = '_'
  !
  ! This is a little awkward, but identifies old non-versioned data format
  if (iconv(is).lt.off_64bit) then  ! iconv(is) must be positive
    istbl(is) = 1   ! Only one Header Block
    !
    if (iconv(is).eq.vax_to_ieee) then
      call gio_cvhd32 (lenbuf,gdfbuf,abuf32,var8ie,var4ie,i4toi4)
    elseif (iconv(is).eq.ieee_to_vax) then
      call gio_cvhd32 (lenbuf,gdfbuf,abuf32,ier8va,ier4va,i4toi4)
    elseif (iconv(is).eq.vax_to_eeei) then
      call gio_cvhd32 (lenbuf,gdfbuf,abuf32,var8ei,var4ei,iei4ei)
    elseif (iconv(is).eq.ieee_to_eeei) then
      call gio_cvhd32 (lenbuf,gdfbuf,abuf32,ier8ei,ier4ei,iei4ei)
    elseif (iconv(is).eq.eeei_to_vax) then
      call gio_cvhd32 (lenbuf,gdfbuf,abuf32,eir8va,eir4va,eii4ie)
    elseif (iconv(is).eq.eeei_to_ieee) then
      call gio_cvhd32 (lenbuf,gdfbuf,abuf32,eir8ie,eir4ie,eii4ie)
    else
      call r4tor4 (gdfbuf,abuf32,lenbuf)
    endif
    !
    iform(is) = abuf32(4)
    indb = abuf32(5)
    !
    call gio_read32header(hd32,abuf32,error)
    call chtoby(gtype,hd32%ijtyp,12)
    !! call gio_hd32_to_gildas_v1 (hd32,gheads(is))
    call gio_hd32_to_gildas_v2 (hd32,gheads(is))
    !
    lndb = indb
    !
    call gio_message(isev,rname,chain)
  else
    !
    jconv = iconv(is)-off_64bit
    !
    ! Prepare required information
    if (jconv.ne.0) then
      call iei4ei(gdfbuf(4),iform(is),1)   ! Just a simple swap
      call iei8ei(gdfbuf(5),jndb,1)        ! This is an I*8 integer
      call iei4ei(gdfbuf(7),istbl(is),1)
    else
      call i4toi4(gdfbuf(4),iform(is),1)
      call i8toi8(gdfbuf(5),jndb,1)        ! This is an I*8 integer
      call i4toi4(gdfbuf(7),istbl(is),1)
    endif
    !
    if (gio_gdfbuf(rname,istbl(is)).eq.0) then
      gio_rih = 0
      return
    endif
    lc = len_trim(chain)
    write(chain(lc+1:),'(A,I4)') ', Blocks: ',istbl(is)
    call gio_message(isev,rname,chain)
    !
    len64 = lenbuf*istbl(is)
    do js=1,istbl(is)
      read(iunit(is),rec=js,iostat=ier) gdfbig(:,js)
    enddo
    !
    if (jconv.eq.vax_to_ieee) then
      call gio_buffer_to_hd64 (len64,gdfbig,hd64,var8ie,var4ie,i4toi4,i8toi8,error)
    elseif (jconv.eq.ieee_to_vax) then
      call gio_buffer_to_hd64 (len64,gdfbig,hd64,ier8va,ier4va,i4toi4,i8toi8,error)
    elseif (jconv.eq.vax_to_eeei) then
      call gio_buffer_to_hd64 (len64,gdfbig,hd64,var8ei,var4ei,iei4ei,ier8ei,error)
    elseif (jconv.eq.ieee_to_eeei) then
      call gio_buffer_to_hd64 (len64,gdfbig,hd64,ier8ei,ier4ei,iei4ei,ier8ei,error)
    elseif (jconv.eq.eeei_to_vax) then
      call gio_buffer_to_hd64 (len64,gdfbig,hd64,eir8va,eir4va,eii4ie,eir8ie,error)
    elseif (jconv.eq.eeei_to_ieee) then
      call gio_buffer_to_hd64 (len64,gdfbig,hd64,eir8ie,eir4ie,eii4ie,eir8ie,error)
    else
      call gio_buffer_to_hd64 (len64,gdfbig,hd64,r8tor8,r4tor4,i4toi4,i8toi8,error)
    endif
    if (error) then
      gio_rih = 0
      return
    endif
    !
    ! Check data type and version number
    if (hd64%version_gdf.gt.code_version_gdf_current) then
      write(chain,'(A,I2,A,I2,A,I2)') 'Unsupported version ', hd64%version_gdf &
           & ,' > ',code_version_gdf_current,' for slot ',is
      call gio_message(seve%e,rname,chain)
      gio_rih = 0
      return
    endif
    !
    call chtoby(gtype,hd64%ijtyp,12)
    call gio_hd64_to_gildas_v2 (hd64,gheads(is),error)
    !
    lndb = jndb
  endif
  !
  ! Sanity check: warn and patch if Nvisi > visibility dimension
  if (gdf_check_nvisi(is,chain).gt.0) then
    call gio_message(seve%w,rname,chain)
    ! Force Nvisi to correct value:
    if (gheads(is)%gil%type_gdf.eq.code_gdf_uvt) then
      gheads(is)%gil%nvisi = gheads(is)%gil%dim(2)
    else
      gheads(is)%gil%nvisi = gheads(is)%gil%dim(1)
    endif
  endif
  !
  ! Check Big Block Size
  isbig(is) = gio_blocking(lndb,istbl(is),.false.)
  !
  ! Define last existing Buffer
  imblock(is) = lndb+istbl(is)
  !
  call gio_form (iform(is),form)
  !
  ! Put additional informations at their appropriate location
  gtype = gheads(is)%char%type ! For the return call
  ivers(is) = gheads(is)%gil%type_gdf
  gheads(is)%gil%form = form
  !
  ! At this stage, we have a true GILDAS header
  gio_rih = 1
end function gio_rih
!
function gio_wih (is,gtype,form,lndb)
  use gio_interfaces, except_this=>gio_wih
  use gildas_def
  use gbl_message
  use gio_image
  use gio_convert
  use gio_headers
  !---------------------------------------------------------------------
  ! @ private
  ! GDF / GIO  Internal routine
  !       Write full header to internal buffer, with format conversion
  !     GIO_RIH / GIO_WIH / GIO_EIH are the only routine addressing
  !             the data format of the header
  !---------------------------------------------------------------------
  integer(kind=4) :: gio_wih  !
  integer(kind=4),             intent(in) :: is     ! Image Slot
  character(len=*),            intent(in) :: gtype  ! Image type
  integer(kind=4),             intent(in) :: form   ! Data format
  integer(kind=record_length), intent(in) :: lndb   ! Number of 512 byte blocks
  ! Global
  external :: iei4ei,eii4ie
  external :: ier8va,ier4va, var8ie,var4ie
  external :: ier8ei,ier4ei, eir8ie,eir4ie
  external :: var8ei,var4ei, eir8va,eir4va
  external :: r8tor8,r4tor4, i4toi4,i8toi8
  ! Local
  character(len=1) :: ficode
  character(len=12) :: gdftit
  logical :: error
  integer(kind=4) :: abuf32(lenbuf)
  type(gildas_header_v1) :: hd32
  type(gildas_header_v2) :: hd64
  integer(kind=4) :: lenb64
  integer(kind=4) :: indb
  integer(kind=8) :: jndb
  integer(kind=4) :: jconv, ier
  integer(kind=record_length), parameter :: lndb_limit=ndb_64bit
  character(len=message_length) :: mess
  character(len=*), parameter :: rname = 'GIO_WIH'
  !
  ! Sanity check ASAP
  if (gdf_check_nvisi(is,mess).gt.0) then
    call gio_message(seve%e,rname,mess)
    call gio_message(seve%e,rname,'Header NOT written')
    gio_wih = 0  ! Error
    return
  endif
  !
  ! Depending on Lndb, we shall select the 32bit or 64bit representation
  if (lndb.gt.lndb_limit.and.istbl(is).lt.2) then
    write (mess,*) 'LNDB ',lndb,' > ',lndb_limit,', forcing 64 bit implementation'
    istbl(is) = 2
  else
    write(mess,*) 'LNDB ',lndb,' < ',lndb_limit,', using default implementation'
  endif
  call gio_message(seve%d,'GDF_WIH',mess)
  !
  ier = gio_gdfbuf(rname,istbl(is))
  if (ier.eq.0) then
    gio_wih = 0
    return
  endif
  !
  error = .false.
  if (istbl(is).eq.1) then
    call bytoch(gtype,hd32%ijtyp,12)
    call gio_gildas_v2_to_hd32 (gheads(is),hd32)
    call gio_write32header(hd32,abuf32,error)
    !
    abuf32(4) = form          ! = iform(is)
    ! print *,'Form ',form,'  = type = ',iform(is),' ',gtype
    indb = lndb
    abuf32(5) = indb
    ! 6 to 11 not used...
    !
    ! Memory to File = - File from Memory
    if (iconv(is).eq.-ieee_fr_vax) then
      call gio_cvhd32 (lenbuf,abuf32,gdfbig,ier8va,ier4va,i4toi4)
      ficode = '_'
    elseif (iconv(is).eq.-eeei_fr_vax) then
      call gio_cvhd32 (lenbuf,abuf32,gdfbig,eir8va,eir4va,eii4ie)
      ficode = '_'
    elseif (iconv(is).eq.-vax_fr_ieee) then
      call gio_cvhd32 (lenbuf,abuf32,gdfbig,var8ie,var4ie,i4toi4)
      ficode = '.'               ! not '-'
    elseif (iconv(is).eq.-eeei_fr_ieee) then
      call gio_cvhd32 (lenbuf,abuf32,gdfbig,eir8ie,eir4ie,eii4ie)
      ficode = '.'               ! not '-'
    elseif (iconv(is).eq.-vax_fr_eeei) then
      call gio_cvhd32 (lenbuf,abuf32,gdfbig,var8ei,var4ei,iei4ei)
      ficode = '-'               ! not '.'
    elseif (iconv(is).eq.-ieee_fr_eeei) then
      call gio_cvhd32 (lenbuf,abuf32,gdfbig,ier8ei,ier4ei,iei4ei)
      ficode = '-'               ! not '.'
    else
      call r4tor4 (abuf32,gdfbig,lenbuf)
      call gio_syscod(ficode)
    endif
    gdftit = gtype
    gdftit(7:7) = ficode
    !
    if (gtype.eq.'GILDAS_IMAGE') then
      ivers(is) = code_gdf_image
    elseif  (gtype.eq.'GILDAS_UVFIL') then
      ivers(is) = code_gdf_uvt
    else
      ivers(is) = 0
    endif
    !
    call chtoby(gdftit,gdfbig,12)
  else
    jndb = lndb
    !
    if (iconv(is).ge.off_64bit) then
      jconv = mod(iconv(is),off_64bit)
    else if (iconv(is).le.-off_64bit) then
      jconv = -mod(-iconv(is),off_64bit)
    else
      jconv = iconv(is)
    endif
    !
    ! This is a patch until the default GILDAS data type contains type_gdf
    if (gtype.eq.'GILDAS_IMAGE') then
      ivers(is) = code_gdf_image
    elseif  (gtype.eq.'GILDAS_UVFIL') then
      ivers(is) = code_gdf_uvt
    else
      ivers(is) = 0
    endif
    !
    ! Convert the current GILDAS header to a 64-bit capable one
    call bytoch(gtype,hd64%ijtyp,12)
    !!call gio_gildas_v1_to_hd64(gheads(is),hd64,error)
    call gio_gildas_v2_to_hd64(gheads(is),hd64,error)
    !
    ! Add missing information
    hd64%form = form
    hd64%ndb = jndb
    hd64%nhb = istbl(is)
    !
    !
    hd64%ntb = 0
    hd64%version_gdf = code_version_gdf_current
    !! hd64%type_gdf = ivers(is) ! No longer correct...
    if (hd64%type_gdf.eq.0) hd64%type_gdf = ivers(is) ! Better, but perhaps also not correct
    !
    !!Print *,'GDF_WIH, Calling GIO_HD64_TO_BUFFER ',jconv
    !
    ! Memory to File = - File from Memory
    call gio_syscod(ficode)
    lenb64 = istbl(is)*lenbuf
    if (jconv.eq.-ieee_fr_vax) then
      call gio_hd64_to_buffer (lenb64,hd64,gdfbig,ier8va,ier4va,i4toi4,i8toi8)
      ficode = '_'
    elseif (jconv.eq.-eeei_fr_vax) then
      call gio_hd64_to_buffer (lenb64,hd64,gdfbig,eir8va,eir4va,eii4ie,eir8ie)
      ficode = '_'
    elseif (jconv.eq.-vax_fr_ieee) then
      call gio_hd64_to_buffer (lenb64,hd64,gdfbig,var8ie,var4ie,i4toi4,i8toi8)
      ficode = '.'               ! not '-'
    elseif (jconv.eq.-eeei_fr_ieee) then
      call gio_hd64_to_buffer (lenb64,hd64,gdfbig,eir8ie,eir4ie,eii4ie,eir8ie)
      ficode = '.'               ! not '-'
    elseif (jconv.eq.-vax_fr_eeei) then
      call gio_hd64_to_buffer (lenb64,hd64,gdfbig,var8ei,var4ei,iei4ei,ier8ei)
      ficode = '-'               ! not '.'
    elseif (jconv.eq.-ieee_fr_eeei) then
      call gio_hd64_to_buffer (lenb64,hd64,gdfbig,ier8ei,ier4ei,iei4ei,ier8ei)
      ficode = '-'               ! not '.'
    else
      !!Print *,'No conversion '
      call gio_hd64_to_buffer (lenb64,hd64,gdfbig,r8tor8,r4tor4,i4toi4,i8toi8)
      call gio_syscod(ficode)
    endif
    !
    ! Set the output file type..
    gdftit = gtype
    if (ficode.eq.'-') then
      ficode = '<'
    else if (ficode.eq.'.') then
      ficode = '>'
    endif
    gdftit(7:7) = ficode
    !
    call chtoby(gdftit,gdfbig,12)
    !!Print *,  'DONE GDF_WIH ',gdftit
  endif
  gio_wih = 1
end function gio_wih
!
function gio_eih (is,gtype,form,lndb)
  use gio_interfaces, except_this=>gio_eih
  use gildas_def
  use gbl_message
  use gio_image
  use gio_convert
  !---------------------------------------------------------------------
  ! @ private
  !  GDF        API routine
  !             Read partial header to prepare an update
  !             Return the Type, the data format and the number of blocks
  !     GIO_RIH / GIO_WIH / GIO_EIH are the only routine addressing
  !             the data format of the header
  !---------------------------------------------------------------------
  integer(kind=4) :: gio_eih
  integer(kind=4),             intent(in)    :: is     ! Image Slot
  character(len=*),            intent(inout) :: gtype  ! Image type
  integer(kind=4),             intent(inout) :: form   ! Data format
  integer(kind=record_length), intent(inout) :: lndb   ! Number of 512 byte blocks
  ! Local
  character(len=12) :: gdftit
  character(len=1) :: sycode
  character(len=128) :: chain
  character(len=*), parameter :: rname = 'GIO_EIH'
  integer :: lc, isev
  integer(kind=4) :: l4ndb
  integer(kind=8) :: l8ndb
  !
  call bytoch (gdfbuf,gdftit,12)
  gio_eih = 0
  if (gdftit(1:6).ne.'GILDAS') return
  call gio_syscod(sycode)
  call convgcod (sycode,gdftit(7:7),iconv(is),chain,isev)
  !
  ! This means not a valid GILDAS file
  if (iconv(is).lt.0) return
  !
  ! We should translate that here, as gio_eih is a standalone routine
  if (iconv(is).lt.off_64bit) then  ! iconv(is) must be positive
    !
    call gio_message(seve%i,rname,chain)
    if (iconv(is).eq.vax_to_ieee) then
      iform(is) = gdfbuf(4)
      l4ndb = gdfbuf(5)
    elseif (iconv(is).eq.ieee_to_vax) then
      iform(is) = gdfbuf(4)
      l4ndb = gdfbuf(5)
    elseif (iconv(is).eq.vax_to_eeei) then
      call iei4ei(gdfbuf(4),iform(is),1)
      call iei4ei(gdfbuf(5),l4ndb,1)
    elseif (iconv(is).eq.ieee_to_eeei) then
      call iei4ei(gdfbuf(4),iform(is),1)
      call iei4ei(gdfbuf(5),l4ndb,1)
    elseif (iconv(is).eq.eeei_to_vax) then
      call eii4ie(gdfbuf(4),iform(is),1)
      call eii4ie(gdfbuf(5),l4ndb,1)
    elseif (iconv(is).eq.eeei_to_ieee) then
      call eii4ie(gdfbuf(4),iform(is),1)
      call eii4ie(gdfbuf(5),l4ndb,1)
    else
      iform(is) = gdfbuf(4)
      l4ndb = gdfbuf(5)
    endif
    !
    ! This is "old" V1 format...
    lndb = l4ndb
    istbl(is) = 1
    !
  else
    if (iconv(is).eq.vax_to_ieee) then
      iform(is) = gdfbuf(4)
      call i8toi8(gdfbuf(5),l8ndb,1)
      istbl(is) = gdfbuf(7)
    elseif (iconv(is).eq.ieee_to_vax) then
      iform(is) = gdfbuf(4)
      call i8toi8(gdfbuf(5),l8ndb,1)
      istbl(is) = gdfbuf(7)
    elseif (iconv(is).eq.vax_to_eeei) then
      call iei4ei(gdfbuf(4),iform(is),1)
      call iei8ei(gdfbuf(5),l8ndb,1)
      call iei4ei(gdfbuf(7),istbl(is),1)
    elseif (iconv(is).eq.ieee_to_eeei) then
      call iei4ei(gdfbuf(4),iform(is),1)
      call iei8ei(gdfbuf(5),l8ndb,1)
      call iei4ei(gdfbuf(7),istbl(is),1)
    elseif (iconv(is).eq.eeei_to_vax) then
      call eii4ie(gdfbuf(4),iform(is),1)
      call eii8ie(gdfbuf(5),l8ndb,1)
      call eii4ie(gdfbuf(7),istbl(is),1)
    elseif (iconv(is).eq.eeei_to_ieee) then
      call eii4ie(gdfbuf(4),iform(is),1)
      call eii8ie(gdfbuf(5),l8ndb,1)
      call eii4ie(gdfbuf(7),istbl(is),1)
    else
      iform(is) = gdfbuf(4)
      call i8toi8(gdfbuf(5),l8ndb,1)
      istbl(is) = gdfbuf(7)
    endif
    lndb = l8ndb
    lc = len_trim(chain)
    write(chain(lc+1:),'(A,I4)') ', Blocks: ',istbl(is)
  endif
  call gio_message(isev,rname,chain)
  !
  call gio_form (iform(is),form)
  gtype = gdftit
  gtype(7:7) = '_'
  gio_eih = 1
  !
  !!Print *,'GDF_EIH ',gdftit,gdfbuf(4),gdfbuf(5)
  !!Print *,'GDF_EIH ',gdftit,iform(is),lndb
end function gio_eih
!
subroutine gio_buffer_to_hd64 (len,inbuf,outhd64,r8,r4,i4,i8,error)
  use gio_headers
  use gio_uv
  !---------------------------------------------------------------------
  ! @ private
  !---------------------------------------------------------------------
  integer(kind=4),        intent(in)    :: len       ! Length of buffer
  integer(kind=4),        intent(in)    :: inbuf(*)  ! Input values in file format
  type(gildas_header_v2), intent(out)   :: outhd64   ! Converted values in machine format
  external                              :: r8        ! Real*8 conversion routine
  external                              :: r4        ! Real*4 conversion routine
  external                              :: i4        ! Integer*4 conversion routine
  external                              :: i8        ! Integer*8 conversion routine
  logical,                intent(inout) :: error     !
  ! Local
  character(len=*), parameter :: rname='GIO_BUFFER_TO_HD64'
  integer :: dim_start, blan_start, extr_start, coor_start, desc_start
  integer :: posi_start, proj_start, spec_start, reso_start, nois_start
  integer :: astr_start, uvda_start, tele_start
  integer :: max_uvda_words
  integer, allocatable :: column_codes(:,:)
  integer :: i, k, ier, nlt
  integer, parameter :: offset=128
  integer(kind=8) :: dim8(gdf_maxdims), ilong
  !
  !  type :: gildas_header_v2
  !
  ! Spread on two or more (stbl) blocks
  !
  ! Block 1: Basic Header and Dimension information
  !  sequence
  !
  !
  ! --- Trailer --------------------------------------------------------
  !  integer(kind=4) :: ityp(3) = 0        !  1  Image Type
  !  integer(kind=4) :: form    = fmt_r4   !  4  Data format (FMT_xx)
  !  integer(kind=8) :: ndb     = 0        !  5  Number of blocks
  !  integer(kind=4) :: nhb     = 2        !  7  Number of header blocks
  !  integer(kind=4) :: ntb     = 0        !  8  Number of trailing blocks
  !  integer(kind=4) :: version_gdf  = code_version_gdf_current  !  9  Data format Version number
  !  integer(kind=4) :: type_gdf  = code_gdf_image   !  10  Or _table, _vo, _uvt, _tuv, _class
  !  integer(kind=4) :: dim_start   = gdf_startdim           !  11  Start offset for DIMENSION, should be odd, >12
  !  ! The maximum value would be 17 to hold up to 8 dimensions.
  call bytoby(inbuf(1),outhd64%ijtyp,12)
  call i4(inbuf(4),outhd64%form,1)
  call i8(inbuf(5),outhd64%ndb,1)
  call i4(inbuf(7),outhd64%nhb,1)
  call i4(inbuf(8),outhd64%ntb,1)
  call i4(inbuf(9),outhd64%version_gdf,1)
  call i4(inbuf(10),outhd64%type_gdf,1)
  call read_and_check_start('DIMENSION',inbuf(11),outhd64%dim_start,error)
  if (error)  return
  !
  ! --- DIMENSION section. Caution about alignment... ------------------
  !  integer(kind=4) :: dim_words   = 2*gdf_maxdims+2            ! at dim_start=11  Dimension section length
  !  integer(kind=4) :: blan_start  !! = dim_start + dim_words + 2   ! 12  Pointer to next section
  !  integer(kind=4) :: mdim    = 4  !or > ! 13  Maximum number of dimensions in this data format
  !  integer(kind=4) :: ndim    = 0        ! 14  Number of dimensions
  !  integer(kind=8) :: dim(gdf_maxdims) = 0      ! 15  Dimensions
  !  !
  dim_start = outhd64%dim_start
  call read_and_check_words('DIMENSION',def_dim_words,inbuf(dim_start),outhd64%dim_words,error)
  if (error)  return
  call read_and_check_start('BLANKING',inbuf(dim_start+1),outhd64%blan_start,error)
  if (error)  return
  call i4(inbuf(dim_start+2),outhd64%mdim,1)
  call i4(inbuf(dim_start+3),outhd64%ndim,1)
  outhd64%dim = 1  ! In case there is 0 dimension
  if (index_length.eq.4) then
     call i8(inbuf(dim_start+4),dim8,outhd64%ndim)
     outhd64%dim = dim8
  else
     call i8(inbuf(dim_start+4),outhd64%dim,outhd64%ndim)
  endif
  !
  ! --- BLANKING section -----------------------------------------------
  !  integer(kind=4) :: blan_words = 2         ! at 41  Blanking section length
  !  integer(kind=4) :: extr_start !! = blan_start + blan_words + 2  ! Pointer to next section
  !  real(kind=4) :: bval = +1.23456e+38   ! 42  Blanking value
  !  real(kind=4) :: eval = -1.0           ! 43  Tolerance
  blan_start = outhd64%blan_start
  call read_and_check_words('BLANKING',def_blan_words,inbuf(blan_start),outhd64%blan_words,error)
  if (error)  return
  call read_and_check_start('EXTREMA',inbuf(blan_start+1),outhd64%extr_start,error)
  if (error)  return
  if (outhd64%blan_words.ne.0) then
    call r4(inbuf(blan_start+2),outhd64%bval,1)
    call r4(inbuf(blan_start+3),outhd64%eval,1)
  endif
  !
  ! --- EXTREMA section ------------------------------------------------
  !  integer(kind=4) :: extr_words = 6         ! Extrema section length
  !  integer(kind=4) :: coor_start !! = extr_start + extr_words +2     !
  !  real(kind=4) :: rmin    = 0.0         ! Minimum
  !  real(kind=4) :: rmax    = 0.0         ! Maximum
  !  integer(kind=8) :: mini = 0           ! Rank 1 pixel of minimum
  !  integer(kind=8) :: maxi = 0           ! Rank 1 pixel of maximum
  extr_start = outhd64%extr_start
  call read_and_check_words('EXTREMA',def_extr_words,inbuf(extr_start),outhd64%extr_words,error)
  if (error)  return
  call read_and_check_start('COORDINATE',inbuf(extr_start+1),outhd64%coor_start,error)
  if (error)  return
  if (outhd64%extr_words.ne.0) then
    call r4(inbuf(extr_start+2),outhd64%rmin,1)
    call r4(inbuf(extr_start+3),outhd64%rmax,1)
    call i8(inbuf(extr_start+4),ilong,1)
    call gdf_index_to_where (ilong,outhd64%ndim,outhd64%dim,outhd64%minloc)
    call i8(inbuf(extr_start+6),ilong,1)
    call gdf_index_to_where (ilong,outhd64%ndim,outhd64%dim,outhd64%maxloc)
    !    call i8(inbuf(extr_start+4),outhd64%mini,1)
    !    call i8(inbuf(extr_start+6),outhd64%maxi,1)
  endif
  !
  ! --- COORDINATE section ---------------------------------------------
  !  integer(kind=4) :: coor_words  = 6*gdf_maxdims   ! at coor_start  Section length
  !  integer(kind=4) :: desc_start  !! = coor_startd + coor_wordsd +2     !
  !  real(kind=8) :: convert(3,gdf_maxdims)       !  Ref, Val, Inc for each dimension
  coor_start = outhd64%coor_start
  call read_and_check_words('COORDINATE',def_coor_words,inbuf(coor_start),outhd64%coor_words,error)
  if (error)  return
  call read_and_check_start('DESCRIPTION',inbuf(coor_start+1),outhd64%desc_start,error)
  if (error)  return
  outhd64%convert = 1.
  if (outhd64%coor_words.ne.0) then
    call r8(inbuf(coor_start+2),outhd64%convert,outhd64%coor_words/2)
  endif
  !
  ! --- DESCRIPTION section --------------------------------------------
  !  integer(kind=4) :: desc_words  = 3*(gdf_maxdims+1) ! at desc_start, Description section length
  !  integer(kind=4) :: null_start  !! = desc_start + desc_words +2     !
  !  integer(kind=4) :: iuni(3)   = 0      ! Data Unit
  !  integer(kind=4) :: icod(3,gdf_maxdims) = 0   ! Axis names
  desc_start = outhd64%desc_start
  call read_and_check_words('DESCRIPTION',def_desc_words,inbuf(desc_start),outhd64%desc_words,error)
  if (error)  return
  call read_and_check_start('NULL',inbuf(desc_start+1),outhd64%null_start,error)
  if (error)  return
  if (outhd64%desc_words.ne.0) then
    call bytoby(inbuf(desc_start+2),outhd64%ijuni,12)
    call bytoby(inbuf(desc_start+2+3),outhd64%ijcod,12*outhd64%ndim)
  endif
  !
  !  ! The first block length is thus
  !  !  dim_start-1 + (2*mdim+4) + (4) + (8) +  (6*mdim+2) + (3*mdim+5)
  !  ! = dim_start-1 + mdim*(2+6+3) + (4+4+2+5+8)
  !  ! = dim_start-1 + 11*mdim + 23
  !  ! With mdim = 7, dim_start=11, this is 110 spaces
  !  ! With mdim = 8, dim_start=11, this is 121 spaces
  !  ! MDIM > 8 would NOT fit in one block...
  !  !
  !  ! Block 2: Ancillary information
  !  !
  !  ! The same logic of Length + Pointer is used there too, although the
  !  ! length are fixed. Note rounding to even number for the pointer offsets
  !  ! in order to preserve alignement...
  !  !
  !  integer(kind=4) :: posi_start  = 1
  !
  ! --- POSITION section -----------------------------------------------
  !  integer(kind=4) :: posi_words    = 15     ! 74  Position section length
  !  integer(kind=4) :: proj_start    !! = posi_start + 18     ! Pointer to next section
  !  integer(kind=4) :: isou(3) = 0        ! 75  Source name
  !  integer(kind=4) :: isys(3) = 0        ! 71  Coordinate System (moved from Description section)
  !  real(kind=8) :: ra         = 0.0      ! 78  Right Ascension
  !  real(kind=8) :: dec        = 0.0      ! 80  Declination
  !  real(kind=8) :: lii        = 0.0      ! 82  Galactic longitude
  !  real(kind=8) :: bii        = 0.0      ! 84           latitude
  !  real(kind=4) :: epoc       = 0.0      ! 86  Epoch of coordinates
  posi_start = offset + 1
  call read_and_check_words('POSITION',def_posi_words,inbuf(posi_start),outhd64%posi_words,error)
  if (error)  return
  call read_and_check_start('PROJECTION',inbuf(posi_start+1),outhd64%proj_start,error)
  if (error)  return
  if (outhd64%posi_words.ne.0) then
    call bytoby(inbuf(posi_start+2),outhd64%ijsou,12)
    call bytoby(inbuf(posi_start+5),outhd64%ijsys,12)
    call r8(inbuf(posi_start+8),outhd64%ra,1)
    call r8(inbuf(posi_start+10),outhd64%dec,1)
    call r8(inbuf(posi_start+12),outhd64%lii,1)
    call r8(inbuf(posi_start+14),outhd64%bii,1)
    call r4(inbuf(posi_start+16),outhd64%epoc,1)
  endif
  !
  ! --- PROJECTION section ---------------------------------------------
  !  integer(kind=4) :: proj_words = 9         ! 87  Projection section length
  !  integer(kind=4) :: spec_start !! = proj_start + 10
  !  real(kind=8) :: a0      = 0.0         ! 89  X of projection center
  !  real(kind=8) :: d0      = 0.0         ! 91  Y of projection center
  !  real(kind=8) :: pang    = 0.0         ! 93  Projection angle
  !  integer(kind=4) :: ptyp = p_none      ! 88  Projection type (see p_... codes)
  !  integer(kind=4) :: xaxi = 0           ! 95  X axis
  !  integer(kind=4) :: yaxi = 0           ! 96  Y axis
  proj_start = outhd64%proj_start
  call read_and_check_words('PROJECTION',def_proj_words,inbuf(proj_start),outhd64%proj_words,error)
  if (error)  return
  call read_and_check_start('SPECTROSCOPY',inbuf(proj_start+1),outhd64%spec_start,error)
  if (error)  return
  if (outhd64%proj_words.ne.0) then
    call r8(inbuf(proj_start+2),outhd64%a0,1)
    call r8(inbuf(proj_start+4),outhd64%d0,1)
    call r8(inbuf(proj_start+6),outhd64%pang,1)
    call i4(inbuf(proj_start+8),outhd64%ptyp,1)
    call i4(inbuf(proj_start+9),outhd64%xaxi,1)
    call i4(inbuf(proj_start+10),outhd64%yaxi,1)
  endif
  !
  ! --- SPECTROSCOPY section -------------------------------------------
  !  integer(kind=4) :: spec_words  = 12       ! 97  Spectroscopy section length
  !  integer(kind=4) :: reso_start  !! = spec_start + 14
  !  real(kind=8) :: fres       = 0.0      !101  Frequency resolution
  !  real(kind=8) :: fima       = 0.0      !103  Image frequency
  !  real(kind=8) :: freq       = 0.0      !105  Rest Frequency
  !  real(kind=4) :: vres       = 0.0      !107  Velocity resolution
  !  real(kind=4) :: voff       = 0.0      !108  Velocity offset
  !  real(kind=4) :: dopp       = 0.0
  !  integer(kind=4) :: faxi    = 0        !109  Frequency axis
  !  integer(kind=4) :: ilin(3) = 0        ! 98  Line name
  spec_start = outhd64%spec_start
  call read_and_check_words('SPECTROSCOPY',def_spec_words,inbuf(spec_start),outhd64%spec_words,error)
  if (error)  return
  call read_and_check_start('RESOLUTION',inbuf(spec_start+1),outhd64%reso_start,error)
  if (error)  return
  if (outhd64%spec_words.ne.0) then
    call r8(inbuf(spec_start+2),outhd64%fres,1)
    call r8(inbuf(spec_start+4),outhd64%fima,1)
    call r8(inbuf(spec_start+6),outhd64%freq,1)
    call r4(inbuf(spec_start+8),outhd64%vres,1)
    call r4(inbuf(spec_start+9),outhd64%voff,1)
    call r4(inbuf(spec_start+10),outhd64%dopp,1)
    call i4(inbuf(spec_start+11),outhd64%faxi,1)
    call bytoby(inbuf(spec_start+12),outhd64%ijlin,12)
    if (outhd64%spec_words.gt.13) then
      call i4(inbuf(spec_start+15),outhd64%vtyp,1)
    else
      outhd64%vtyp = 0
    endif
  endif
  !
  ! --- RESOLUTION section ---------------------------------------------
  !  integer(kind=4) :: reso_words = 3         !110  Resolution section length
  !  integer(kind=4) :: nois_start !! = reso_start + 6
  !  real(kind=4) :: majo    = 0.0         !111  Major axis
  !  real(kind=4) :: mino    = 0.0         !112  Minor axis
  !  real(kind=4) :: posa    = 0.0         !113  Position angle
  reso_start = outhd64%reso_start
  call read_and_check_words('RESOLUTION',def_reso_words,inbuf(reso_start),outhd64%reso_words,error)
  if (error)  return
  call read_and_check_start('NOISE',inbuf(reso_start+1),outhd64%nois_start,error)
  if (error)  return
  if (outhd64%reso_words.ne.0) then
    call r4(inbuf(reso_start+2),outhd64%majo,1)
    call r4(inbuf(reso_start+3),outhd64%mino,1)
    call r4(inbuf(reso_start+4),outhd64%posa,1)
  endif
  !
  ! --- NOISE section --------------------------------------------------
  !  integer(kind=4) :: nois_words = 2         ! 114 Noise section length
  !  integer(kind=4) :: astr_start !! = nois_start + 4
  !  real(kind=4) :: noise   = 0.0         ! 115 Theoretical noise
  !  real(kind=4) :: rms     = 0.0         ! 116 Actual noise
  nois_start = outhd64%nois_start
  call read_and_check_words('NOISE',def_nois_words,inbuf(nois_start),outhd64%nois_words,error)
  if (error)  return
  call read_and_check_start('ASTROMETRY',inbuf(nois_start+1),outhd64%astr_start,error)
  if (error)  return
  if (outhd64%nois_words.ne.0) then
    call r4(inbuf(nois_start+2),outhd64%noise,1)
    call r4(inbuf(nois_start+3),outhd64%rms,1)
  endif
  !
  ! --- ASTROMETRY section ---------------------------------------------
  !  integer(kind=4) :: astr_words  = 4         ! 117 Proper motion section length
  !  integer(kind=4) :: uvda_start !! = astr_start + 4
  !  real(kind=4) :: mura     = 0.0        ! 118 along RA, in mas/yr
  !  real(kind=4) :: mudec    = 0.0        ! 119 along Dec, in mas/yr
  !  real(kind=4) :: parallax = 0.0        ! 120 in mas
  !!  ! real(kind=4) :: pepoch   = 2000.0     ! 121 in yrs ?
  astr_start = outhd64%astr_start
  call read_and_check_words('ASTROMETRY',def_astr_words,inbuf(astr_start),outhd64%astr_words,error)
  if (error)  return
  call read_and_check_start('UV_DATA',inbuf(astr_start+1),outhd64%uvda_start,error)
  if (error) return
  if (outhd64%astr_words.ne.0) then
    call r4(inbuf(astr_start+2),outhd64%mura,1)
    call r4(inbuf(astr_start+3),outhd64%mudec,1)
    call r4(inbuf(astr_start+4),outhd64%parallax,1)
  endif
  !
  ! --- UV_DATA information --------------------------------------------
  !  integer(kind=4) :: uvda_words  =  ! Length of section, variable
  !  integer(kind=4) :: tele_start  !! = uvda_start + uvda_words + 2
  !  integer(kind=4) :: version            ! version number. Will allow us to change the data format
  !  integer(kind=4) :: nchan              ! Number of channels
  !
  uvda_start = outhd64%uvda_start
  !  The length of this section is variable
  !  It can be def_uvdata_words + 3*outhd64%nchan
  !  but outhd64%nchan is not yet defined. We use dim(1) instead
  max_uvda_words = def_uvda_words+3*outhd64%dim(1)
  call read_and_check_words('UV_DATA',max_uvda_words,inbuf(uvda_start),outhd64%uvda_words,error)
  if (error)  then
    Print *,'Expected UVDA length ',def_uvda_words, max_uvda_words
    Print *,'Found length ',outhd64%uvda_words
    error = .false.
  endif
  call read_and_check_start('TELESCOPE',inbuf(uvda_start+1),outhd64%tele_start,error)
  if (error)  return
  if (outhd64%uvda_words.ne.0) then
    call i4(inbuf(uvda_start+2),outhd64%version_uv,1)
    call i4(inbuf(uvda_start+3),outhd64%nchan,1)
    call i8(inbuf(uvda_start+4),outhd64%nvisi,1)
    call i4(inbuf(uvda_start+6),outhd64%nstokes,1)
    call r4(inbuf(uvda_start+7),outhd64%basemin,1)
    call r4(inbuf(uvda_start+8),outhd64%basemax,1)
    !
    ! All the rest is being debated
    !  ! All the rest is being debated
    !  integer(kind=4) :: fcol              ! "Column" of first channel
    !  integer(kind=4) :: lcol              ! "Column" of last channel
    call i4(inbuf(uvda_start+9),outhd64%fcol,1)
    call i4(inbuf(uvda_start+10),outhd64%lcol,1)
    ! the number of information per channel can be obtained by (lcol-fcol+1)/nchan
    ! so this could allow to derive the number of Stokes parameters
    !
    !  ! Leading data at start of each visibility contains specific information
    !  integer(kind=4) :: nlead              ! Number of leading informations (at lest 7)
    !  ! Trailing data at end of each visibility may hold additional information
    !  integer(kind=4) :: ntrail             ! Number of trailing informations
    call i4(inbuf(uvda_start+11),outhd64%nlead,1)
    call i4(inbuf(uvda_start+12),outhd64%ntrail,1)
    !
    nlt = outhd64%nlead + outhd64%ntrail
    !! Print *,'Lead / Trail ', outhd64%fcol, outhd64%lcol, outhd64%nlead, outhd64%ntrail
    allocate (column_codes(2,nlt),stat=ier)
    call i4(inbuf(uvda_start+13),column_codes,2*nlt)
    !! Print *,(column_codes(1:2,i),i=1,nlt)
    !
    ! Set the back pointers
    outhd64%column_pointer = code_null
    outhd64%column_size = 0
    do i = 1, outhd64%nlead+outhd64%ntrail
      if (column_codes(2,i).ne.0) then
        if (column_codes(1,i).gt.code_uvt_last) then
          Print *,'ERROR : This version of GILDAS does not support Code ',column_codes(1,i)
        else
          if (i.gt.outhd64%nlead) then
            outhd64%column_pointer(column_codes(1,i)) = i+outhd64%lcol-outhd64%nlead
          else
            outhd64%column_pointer(column_codes(1,i)) = i
          endif
          outhd64%column_size(column_codes(1,i)) = column_codes(2,i)
        endif
      endif
    enddo
    deallocate(column_codes)
    !
    ! Get the additional Frequency / Stokes information
    call i4(inbuf(uvda_start+13+2*nlt),outhd64%order,1)
    call i4(inbuf(uvda_start+14+2*nlt),outhd64%nfreq,1)
    call i4(inbuf(uvda_start+15+2*nlt),outhd64%atoms,4)
    if (outhd64%nfreq.ne.0) then
      ! Has Freqs AND Stokes
      allocate(outhd64%stokes(outhd64%nfreq),outhd64%freqs(outhd64%nfreq), stat=ier)
      call r8(inbuf(uvda_start+19+2*nlt),outhd64%freqs,outhd64%nfreq)
      call i4(inbuf(uvda_start+19+2*nlt+2*outhd64%nfreq),outhd64%stokes,outhd64%nfreq)
    else if (abs(outhd64%order).eq.abs(code_stok_chan)) then
      ! Only Stokes
      allocate(outhd64%stokes(outhd64%nstokes), stat=ier)
      call i4(inbuf(uvda_start+19+2*nlt),outhd64%stokes,outhd64%nstokes)
    endif
  endif
  !
  ! --- TELESCOPE section ----------------------------------------------
  ! The tele section here follows the UV Data section
  !   integer(kind=4) :: tele_words  ! Telescope section length
  !   integer(kind=4) :: void_start  ! Pointer to next section (unused)
  !   integer(kind=4) :: nteles      ! Number of telescopes
  ! Then for each telescope
  !   real(kind=8)    :: lon         ! Longitude (radians)
  !   real(kind=8)    :: lat         ! Latitude  (radians)
  !   real(kind=4)    :: alt         ! Altitude (m)
  !   real(kind=4)    :: diam        ! Diameter
  !   integer(kind=4) :: ijtele(3)   ! Telescope name
  tele_start = outhd64%tele_start
  call read_and_check_words('TELESCOPE',3+100*9,  &  ! Allow for up to 100 (!!!) telescopes
     inbuf(tele_start),outhd64%tele_words,error)
  if (error)  return
  if (outhd64%tele_words.ne.0) then
    !!Print *,'W-GIO_BUFFER_TO_HD64, Telescope section still experimental'
    call i4(inbuf(tele_start+2),outhd64%nteles,1)
    !!Print *,'W-GIO_BUFFER_TO_HD64, # Telescopes ',outhd64%nteles
    allocate(outhd64%teles(outhd64%nteles),stat=ier)
    if (outhd64%tele_words.gt.3) then
      call i4(inbuf(tele_start+3),outhd64%magic,1)
      !!Print *,'MagicT  ',outhd64%magic
      k = 4
      do i=1,outhd64%nteles
        !!Print *,'I ',i,k,outhd64%tele_words,' LEN ',len,tele_start+outhd64%tele_words
        if (k .gt. outhd64%tele_words) exit
        call r8(inbuf(k+tele_start),outhd64%teles(i)%lon,1)
        !!Print *,'Lon ',outhd64%teles(i)%lon
        k = k+2
        if (k .gt. outhd64%tele_words) exit
        call r8(inbuf(k+tele_start),outhd64%teles(i)%lat,1)
        !!Print *,'Lat ',outhd64%teles(i)%lat
        k = k+2
        if (k .gt. outhd64%tele_words) exit
        call r4(inbuf(k+tele_start),outhd64%teles(i)%alt,1)
        !!Print *,'Alt ',outhd64%teles(i)%alt
        k = k+1
        if (k .gt. outhd64%tele_words) exit
        call r4(inbuf(k+tele_start),outhd64%teles(i)%diam,1)
        !!Print *,'Diam ',outhd64%teles(i)%diam
        k = k+1
        if (k .gt. outhd64%tele_words) exit
        call bytoby(inbuf(k+tele_start),outhd64%teles(i)%ctele,12)
        !!Print *,'Telescope ',outhd64%teles(i)%ctele
        k = k+3
        if (k .gt. outhd64%tele_words) exit
        ! Skip padding
        k = k+1
        if (k .gt. outhd64%tele_words) exit
      enddo
    endif
  endif
  !
contains
  !
  subroutine read_and_check_words(name,mwords,buf,nwords,error)
    use gbl_message
    !-------------------------------------------------------------------
    ! Read the number of words of the current section, check for a valid
    ! value, raise error message if relevant.
    !-------------------------------------------------------------------
    character(len=*), intent(in)    :: name    ! Related section name
    integer(kind=4),  intent(in)    :: mwords  ! Max value expected
    integer(kind=4),  intent(in)    :: buf     ! Raw value
    integer(kind=4),  intent(out)   :: nwords  ! Converted value
    logical,          intent(inout) :: error   !
    ! Local
    character(len=message_length) :: mess
    !
    call i4(buf,nwords,1)
    if (nwords.ge.0 .and. nwords.le.mwords)  return
    !
    ! There is hardly anything we can do with this header nor the data.
    ! May be dumping what we have read up to now for debugging.
    write(mess,'(3A,2(I0,A))')  'Number of words of the ',name,  &
      ' section is unexpected (found ',nwords,', max is ',mwords,')'
    call gio_message(seve%e,rname,mess)
    call gio_message(seve%e,rname,'Can not read header beyond this point. File corrupted?')
    error = .true.
    return
  end subroutine read_and_check_words
  !
  subroutine read_and_check_start(name,buf,start,error)
    use gbl_message
    !-------------------------------------------------------------------
    ! Read the starting position of the next section, check for a valid
    ! value, raise an error message if relevant.
    !-------------------------------------------------------------------
    character(len=*), intent(in)    :: name   ! Related section name
    integer(kind=4),  intent(in)    :: buf    ! Raw value
    integer(kind=4),  intent(out)   :: start  ! Converted value
    logical,          intent(inout) :: error  !
    ! Local
    character(len=message_length) :: mess
    !
    call i4(buf,start,1)
    ! By design, the section start lies in the buffer
    if (start.ge.1 .and. start.le.len)  return
    !
    ! There is hardly anything we can do with this header nor the data.
    ! May be dumping what we have read up to now for debugging.
    write(mess,'(A,A,A,I0,A)')  'Start of ',name,' section is unexpected (',start,')'
    call gio_message(seve%e,rname,mess)
    call gio_message(seve%e,rname,'Can not read header beyond this point. File corrupted?')
    error = .true.
    return
  end subroutine read_and_check_start
  !
end subroutine gio_buffer_to_hd64
!
subroutine gio_hd64_to_buffer (len,inhd64,outbuf,r8,r4,i4,i8)
  use gio_headers
  use gio_uv
  !---------------------------------------------------------------------
  ! @ private
  !---------------------------------------------------------------------
  integer(kind=4), intent(inout)  :: len    ! Length of buffer
  integer(kind=4), intent(out) :: outbuf(*) ! Input values in file format
  type (gildas_header_v2), intent(inout) :: inhd64  ! Converted values in machine format
  external :: r8                    ! Real*8 conversion routine
  external :: r4                    ! Real*4 conversion routine
  external :: i4                    ! Integer*4 conversion routine
  external :: i8                    ! Integer*8 conversion routine
  ! Local
  integer :: i, j, k, ier, nlt, itrail
  !
  integer :: dim_start, blan_start, extr_start, coor_start, desc_start
  integer :: posi_start, proj_start, spec_start, reso_start, nois_start
  integer :: astr_start, uvda_start, tele_start
  integer, parameter :: offset=128
  integer, allocatable :: column_codes(:,:)
  integer(kind=8) :: dim8(gdf_maxdims), ilong
  !
  outbuf(1:len) = 0
  !
  !  type :: gildas_header_v2
  !
  ! Spread on two or more blocks
  !
  ! Block 1: Basic Header and Dimension information
  !  sequence
  !
  !
  ! Trailer:
  !  integer(kind=4) :: ityp(3) = 0        !  1  Image Type
  !  integer(kind=4) :: form    = fmt_r4   !  4  Data format (FMT_xx)
  !  integer(kind=8) :: ndb     = 0        !  5  Number of blocks
  !  integer(kind=4) :: nhb     = 2        !  7  Number of header blocks
  !  integer(kind=4) :: ntb     = 0        !  8  Number of trailing blocks
  !  integer(kind=4) :: version_gdf  = code_version_gdf_current  !  9  Data format Version number
  !  integer(kind=4) :: type_gdf  = data_image       !  10  Or data_table, data_uvt, data_tuv, data_class
  !  integer(kind=4) :: dim_start   = gdf_startdim   !  11  Start offset for DIMENSION, should be odd, >12
  !  ! The maximum value would be 17 to hold up to 8 dimensions.
  call bytoby(inhd64%ijtyp,outbuf(1),12)
  call i4(inhd64%form,outbuf(4),1)
  call i8(inhd64%ndb,outbuf(5),1)
  call i4(inhd64%nhb,outbuf(7),1)
  call i4(inhd64%ntb,outbuf(9),1)
  call i4(inhd64%version_gdf,outbuf(9),1)
  call i4(inhd64%type_gdf,outbuf(10),1)
  inhd64%dim_start = gdf_startdim
  call i4(inhd64%dim_start,outbuf(11),1)
  !
  ! DIMENSION Section. Caution about alignment...
  !
  dim_start = inhd64%dim_start
  !!Print *,'GIO_HD64_TO_BUFFER dim_start',dim_start
  inhd64%mdim = gdf_maxdims                     !
  inhd64%dim_words = 2 + 2*inhd64%mdim   !
  call i4(inhd64%dim_words,outbuf(dim_start),1)
  inhd64%blan_start = dim_start + inhd64%dim_words + 2
  call i4(inhd64%blan_start,outbuf(dim_start+1),1)
  call i4(inhd64%mdim,outbuf(dim_start+2),1)
  call i4(inhd64%ndim,outbuf(dim_start+3),1)
  !
  if (index_length.eq.4) then
    dim8 = inhd64%dim
    call i8(dim8,outbuf(dim_start+4),inhd64%ndim)
  else
    call i8(inhd64%dim,outbuf(dim_start+4),inhd64%ndim)
  endif
  !!Print *,'dim',inhd64%ndim,inhd64%dim
  ! BLANKING
  blan_start = inhd64%blan_start
  !!Print *,'GIO_HD64_TO_BUFFER blan_start',blan_start,inhd64%blan_words
  if (inhd64%blan_words.ne.0) inhd64%blan_words = def_blan_words
  call i4(inhd64%blan_words,outbuf(blan_start),1)
  inhd64%extr_start = blan_start + inhd64%blan_words + 2
  call i4(inhd64%extr_start,outbuf(blan_start+1),1)
  if (inhd64%blan_words.ne.0) then
    call r4(inhd64%bval,outbuf(blan_start+2),1)
    call r4(inhd64%eval,outbuf(blan_start+3),1)
  endif
  !
  ! EXTREMA
  extr_start = inhd64%extr_start
  if (inhd64%extr_words.ne.0) inhd64%extr_words = def_extr_words
  !!Print *,'GIO_HD64_TO_BUFFER extr_start',extr_start,inhd64%extr_words
  call i4(inhd64%extr_words,outbuf(extr_start),1)
  inhd64%coor_start = extr_start + inhd64%extr_words + 2
  call i4(inhd64%coor_start,outbuf(extr_start+1),1)
  if (inhd64%extr_words.ne.0) then
    call r4(inhd64%rmin,outbuf(extr_start+2),1)
    call r4(inhd64%rmax,outbuf(extr_start+3),1)
    call gdf_where_to_index (ilong,inhd64%ndim,inhd64%dim,inhd64%minloc)
    call i8(ilong,outbuf(extr_start+4),1)
    call gdf_where_to_index (ilong,inhd64%ndim,inhd64%dim,inhd64%maxloc)
    call i8(ilong,outbuf(extr_start+6),1)
!    call i8(inhd64%mini,outbuf(extr_start+4),1)
!    call i8(inhd64%maxi,outbuf(extr_start+6),1)
  endif
  !
  ! COORDINATE Section
  coor_start = inhd64%coor_start
  if (inhd64%coor_words.ne.0) inhd64%coor_words = 6*gdf_maxdims
  !!Print *,'GIO_HD64_TO_BUFFER coor_start',coor_start,inhd64%coor_words
  call i4(inhd64%coor_words,outbuf(coor_start),1)
  inhd64%desc_start = coor_start + inhd64%coor_words + 2
  call i4(inhd64%desc_start,outbuf(coor_start+1),1)
  if (inhd64%coor_words.ne.0) then
    call r8(inhd64%convert,outbuf(coor_start+2),inhd64%coor_words/2)
  endif
  !
  ! DESCRIPTION Section
  inhd64%desc_start = coor_start+2+inhd64%coor_words
  desc_start = inhd64%desc_start
  if (inhd64%desc_words.ne.0) inhd64%desc_words = 3+3*gdf_maxdims
  !!Print *,'GIO_HD64_TO_BUFFER desc_start',desc_start,inhd64%desc_words
  call i4(inhd64%desc_words,outbuf(desc_start),1)
  inhd64%null_start = desc_start + inhd64%desc_words + 2
  call i4(inhd64%null_start,outbuf(desc_start+1),1)
  if (inhd64%desc_words.ne.0) then
    call bytoby(inhd64%ijuni,outbuf(desc_start+2),12)
    call bytoby(inhd64%ijcod,outbuf(desc_start+5),12*inhd64%ndim)
  endif
  !  !
  !  ! The first block length is thus
  !  !  dim_start-1 + (2*mdim+4) + (4) + (8) +  (6*mdim+2) + (3*mdim+5)
  !  ! = dim_start-1 + mdim*(2+6+3) + (4+4+2+5+8)
  !  ! = dim_start-1 + 11*mdim + 23
  !  ! With mdim = 7, dim_start=11, this is 110 spaces
  !  ! With mdim = 8, dim_start=11, this is 121 spaces
  !  ! MDIM > 8 would NOT fit in one block...
  !  !
  !  ! Block 2: Ancillary information
  !  !
  !  ! The same logic of Length + Pointer is used there too, although the
  !  ! lengths are fixed. Note rounding to even number for the pointer offsets
  !  ! in order to preserve alignement...
  !  !
  ! POSITION
  posi_start = offset + 1
  if (inhd64%posi_words.ne.0) inhd64%posi_words = def_posi_words
  !!Print *,'GIO_HD64_TO_BUFFER posi_start',posi_start,inhd64%posi_words
  call i4(inhd64%posi_words,outbuf(posi_start),1)
  inhd64%proj_start = posi_start + inhd64%posi_words + 2
  call i4(inhd64%proj_start,outbuf(posi_start+1),1)
  if (inhd64%posi_words.ne.0) then
    call bytoby(inhd64%ijsou,outbuf(posi_start+2),12)
    call bytoby(inhd64%ijsys,outbuf(posi_start+5),12)
    call r8(inhd64%ra,outbuf(posi_start+8),1)
    call r8(inhd64%dec,outbuf(posi_start+10),1)
    call r8(inhd64%lii,outbuf(posi_start+12),1)
    call r8(inhd64%bii,outbuf(posi_start+14),1)
    call r4(inhd64%epoc,outbuf(posi_start+16),1)
  endif
  ! !
  !  ! PROJECTION
  !  integer(kind=4) :: proj_words = 9         ! 87  Projection section length
  !  integer(kind=4) :: spec_start !! = proj_start + 12
  !  real(kind=8) :: a0      = 0.0         ! 89  X of projection center
  !  real(kind=8) :: d0      = 0.0         ! 91  Y of projection center
  !  real(kind=8) :: pang    = 0.0         ! 93  Projection angle
  !  integer(kind=4) :: ptyp = p_none      ! 88  Projection type (see p_... codes)
  !  integer(kind=4) :: xaxi = 0           ! 95  X axis
  !  integer(kind=4) :: yaxi = 0           ! 96  Y axis
  !  !
  proj_start = inhd64%proj_start
  if (inhd64%proj_words.ne.0) inhd64%proj_words = def_proj_words
  !!Print *,'GIO_HD64_TO_BUFFER proj_start',proj_start,inhd64%proj_words
  call i4(inhd64%proj_words,outbuf(proj_start),1)
  inhd64%spec_start = proj_start + inhd64%proj_words + 2
  call i4(inhd64%spec_start,outbuf(proj_start+1),1)
  if (inhd64%proj_words.ne.0) then
    call r8(inhd64%a0,outbuf(proj_start+2),1)
    call r8(inhd64%d0,outbuf(proj_start+4),1)
    call r8(inhd64%pang,outbuf(proj_start+6),1)
    call i4(inhd64%ptyp,outbuf(proj_start+8),1)
    call i4(inhd64%xaxi,outbuf(proj_start+9),1)
    call i4(inhd64%yaxi,outbuf(proj_start+10),1)
  endif
  !
  !  ! SPECTROSCOPY
  !  integer(kind=4) :: spec_words  = 12       ! 97  Spectroscopy section length
  !  integer(kind=4) :: reso_start  !! = spec_start + 14
  !  real(kind=8) :: fres       = 0.0      !101  Frequency resolution
  !  real(kind=8) :: fima       = 0.0      !103  Image frequency
  !  real(kind=8) :: freq       = 0.0      !105  Rest Frequency
  !  real(kind=4) :: vres       = 0.0      !107  Velocity resolution
  !  real(kind=4) :: voff       = 0.0      !108  Velocity offset
  !  integer(kind=4) :: faxi    = 0        !109  Frequency axis
  !  integer(kind=4) :: ilin(3) = 0        ! 98  Line name
  spec_start = inhd64%spec_start
  if (inhd64%spec_words.ne.0) inhd64%spec_words = def_spec_words
  !!Print *,'GIO_HD64_TO_BUFFER spec_start',spec_start,inhd64%spec_words
  call i4(inhd64%spec_words,outbuf(spec_start),1)
  inhd64%reso_start = spec_start + inhd64%spec_words + 2
  call i4(inhd64%reso_start,outbuf(spec_start+1),1)
  if (inhd64%spec_words.ne.0) then
    call r8(inhd64%fres,outbuf(spec_start+2),1)
    call r8(inhd64%fima,outbuf(spec_start+4),1)
    call r8(inhd64%freq,outbuf(spec_start+6),1)
    call r4(inhd64%vres,outbuf(spec_start+8),1)
    call r4(inhd64%voff,outbuf(spec_start+9),1)
    call r4(inhd64%dopp,outbuf(spec_start+10),1)
    call i4(inhd64%faxi,outbuf(spec_start+11),1)
    call bytoby(inhd64%ijlin,outbuf(spec_start+12),12)
    call i4(inhd64%vtyp,outbuf(spec_start+15),1)
  endif
  !  !
  !  ! RESOLUTION
  !  integer(kind=4) :: reso_words = 3         !110  Resolution section length
  !  integer(kind=4) :: nois_start !! = reso_start + 6
  !  real(kind=4) :: majo    = 0.0         !111  Major axis
  !  real(kind=4) :: mino    = 0.0         !112  Minor axis
  !  real(kind=4) :: posa    = 0.0         !113  Position angle
  reso_start = inhd64%reso_start
  if (inhd64%reso_words.ne.0) inhd64%reso_words = def_reso_words
  !!Print *,'GIO_HD64_TO_BUFFER reso_start',reso_start,inhd64%reso_words
  call i4(inhd64%reso_words,outbuf(reso_start),1)
  inhd64%nois_start = reso_start + inhd64%reso_words + 2
  call i4(inhd64%nois_start,outbuf(reso_start+1),1)
  if (inhd64%reso_words.ne.0) then
    call r4(inhd64%majo,outbuf(reso_start+2),1)
    call r4(inhd64%mino,outbuf(reso_start+3),1)
    call r4(inhd64%posa,outbuf(reso_start+4),1)
  endif
  !  !
  !  ! NOISE
  !  integer(kind=4) :: nois_words = 2         ! 114 Noise section length
  !  integer(kind=4) :: astr_start !! = nois_start + 4
  !  real(kind=4) :: noise   = 0.0         ! 115 Theoretical noise
  !  real(kind=4) :: rms     = 0.0         ! 116 Actual noise
  nois_start = inhd64%nois_start
  if (inhd64%nois_words.ne.0) inhd64%nois_words = def_nois_words
  call i4(inhd64%nois_words,outbuf(nois_start),1)
  inhd64%astr_start = nois_start + inhd64%nois_words + 2
  call i4(inhd64%astr_start,outbuf(nois_start+1),1)
  if (inhd64%nois_words.ne.0) then
    call r4(inhd64%noise,outbuf(nois_start+2),1)
    call r4(inhd64%rms,outbuf(nois_start+3),1)
  endif
  !  !
  !  ! ASTROMETRY
  !  integer(kind=4) :: astr_words  = 4         ! 117 Proper motion section length
  !  integer(kind=4) :: uvda_start !! = astr_start + 4
  !  real(kind=4) :: mura     = 0.0        ! 118 along RA, in mas/yr
  !  real(kind=4) :: mudec    = 0.0        ! 119 along Dec, in mas/yr
  !  real(kind=4) :: parallax = 0.0        ! 120 in mas
  !!  ! real(kind=4) :: pepoch   = 2000.0     ! 121 in yrs ?
  astr_start = inhd64%astr_start
  if (inhd64%astr_words.ne.0) inhd64%astr_words = def_astr_words
  call i4(inhd64%astr_words,outbuf(astr_start),1)
  inhd64%uvda_start = astr_start + inhd64%astr_words + 2
  call i4(inhd64%uvda_start,outbuf(astr_start+1),1)
  if (inhd64%astr_words.ne.0) then
    call r4(inhd64%mura,outbuf(astr_start+2),1)
    call r4(inhd64%mudec,outbuf(astr_start+3),1)
    call r4(inhd64%parallax,outbuf(astr_start+4),1)
  endif
  ! !
  !  ! UV_DATA information
  !  integer(kind=4) :: uvda_words  =  ! Length of section, variable
  !  integer(kind=4) :: tele_start  !! = uvda_start + uvda_words + 2
  !  integer(kind=4) :: version            ! version number. Will allow us to change the data format
  !  integer(kind=4) :: nchan              ! Number of channels
  !  !
  uvda_start = inhd64%uvda_start
  !!Print *,'GIO_HD64_TO_BUFFER uvda_start',uvda_start, inhd64%nfreq
  if (inhd64%uvda_words.ne.0) then
    ! Compute the length
    nlt = inhd64%nlead + inhd64%ntrail
    ! If we use the current number of additional information, we
    !   cannot extend the Table (in tuv order) without possibly
    !   changing the number of Header Blocks.
    inhd64%uvda_words = 12+2*nlt+6
    ! so a possible solution is to pre-allocate the maximum number
    !   but is it worth ?
    ! inhd64%uvda_words = 12+2*code_uvt_last+6
    !
    if (inhd64%nfreq.ne.0) then
      inhd64%uvda_words = inhd64%uvda_words+3*inhd64%nfreq
    else
      if (abs(inhd64%order).eq.abs(code_stok_chan)) then
        inhd64%uvda_words = inhd64%uvda_words+inhd64%nstokes
      endif
    endif
    ! Make it even
    if (mod(inhd64%uvda_words,2).ne.0) inhd64%uvda_words = inhd64%uvda_words + 1
    !
    call i4(inhd64%uvda_words,outbuf(uvda_start),1)
    inhd64%tele_start = uvda_start + inhd64%uvda_words + 2
    call i4(inhd64%tele_start,outbuf(uvda_start+1),1)
    !
    ! Bug correction Nov-06 2014: was incorrectly version_gdf before
    call i4(inhd64%version_uv,outbuf(uvda_start+2),1)
    call i4(inhd64%nchan,outbuf(uvda_start+3),1)
    call i8(inhd64%nvisi,outbuf(uvda_start+4),1)
    call i4(inhd64%nstokes,outbuf(uvda_start+6),1)
    call r4(inhd64%basemin,outbuf(uvda_start+7),1)
    call r4(inhd64%basemax,outbuf(uvda_start+8),1)
    !
    !  ! All the rest is being debated
    !  integer(kind=4) :: fcol              ! "Column" of first channel
    !  integer(kind=4) :: lcol              ! "Column" of last channel
    !! Print *,'Lead / Trail ',inhd64%fcol,inhd64%lcol,inhd64%nlead,inhd64%ntrail
    call i4(inhd64%fcol,outbuf(uvda_start+9),1)
    call i4(inhd64%lcol,outbuf(uvda_start+10),1)
    ! the number of information per channel can be obtained by (lcol-fcol+1)/nchan
    ! so this could allow to derive the number of Stokes parameters
    !  !
    !  ! Leading data at start of each visibility contains specific information
    !  integer(kind=4) :: nlead              ! Number of leading informations (at lest 7)
    !  ! Trailing data at end of each visibility may hold additional information
    !  integer(kind=4) :: ntrail             ! Number of trailing informations
    call i4(inhd64%nlead,outbuf(uvda_start+11),1)
    if (inhd64%nlead.ne.7) then
      Print *,'Suspicious value of NLEAD ',inhd64%nlead, ' correct if needed'
      !! inhd64%nlead = 7
      read(5,*) inhd64%nlead
    endif
    if (inhd64%ntrail.gt.code_uvt_last) then
      Print *,'Suspicious value of NTRAIL ',inhd64%ntrail, ' correct if needed'
      read(5,*) inhd64%ntrail
      !! inhd64%ntrail = 2
    endif
    call i4(inhd64%ntrail,outbuf(uvda_start+12),1)
    !!Print *,'NLT ',nlt,inhd64%nlead,inhd64%ntrail
    !
    ! This coding is redundant : fcol = nlead+1  and lcol+ntrail = visi_size
    !
    ! Leading / Trailing information codes have been specified before
    ! integer(kind=4) :: column_pointer(code_uvt_last) = 0 ! Back pointer to the columns...
    ! ! In the data, we instead have the codes for each column
    ! integer(kind=4) :: column_codes(2,nlead+ntrail)    ! Leading / Trailing information codes
    allocate (column_codes(2,nlt),stat=ier)
    if (inhd64%ntrail.gt.code_uvt_last.or.ier.ne.0) then
      Print *,'Cannot allocate column codes'
      return
    endif
    column_codes = 0
    do j = 1,nlt
      do i = 1, code_uvt_last
        if (inhd64%column_pointer(i).lt.inhd64%fcol) then
          if (inhd64%column_pointer(i).eq.j) then
            column_codes(1,j) = i
            column_codes(2,j) = inhd64%column_size(i)
            exit
          endif
        else if (inhd64%column_pointer(i).gt.inhd64%lcol) then
           ! A little more vicious if > nlead
          itrail = inhd64%column_pointer(i)-inhd64%lcol+inhd64%nlead
          !! Print *,'Trail ',j,i,itrail
          if (itrail.eq.j) then
            column_codes(1,j) = i
            column_codes(2,j) = inhd64%column_size(i)
            exit
          endif
        else
          Print *,'Inconsistent Column Pointer #',i,' = ', inhd64%column_pointer(i), &
          &   ' in data range',inhd64%fcol,inhd64%lcol
        endif
      enddo
    enddo
    !! Print *,"(column_codes(1:2,i),i=1,nlt)"
    !! Print *,(column_codes(1:2,i),i=1,nlt)
    !
    call i4(column_codes,outbuf(uvda_start+13),2*nlt)
    deallocate(column_codes)
    !
    ! Is this the place for such information ?
    ! It can be arbitrarily long, so it can use an arbitrary size for the header ...
    !
    !    integer(kind=4) :: nfreq                 ! 0 or = nchan*nstokes
    call i4(inhd64%order,outbuf(uvda_start+13+2*nlt),1)
    call i4(inhd64%nfreq,outbuf(uvda_start+14+2*nlt),1)
    call i4(inhd64%atoms,outbuf(uvda_start+15+2*nlt),4)
    if (inhd64%nfreq.ne.0) then
      ! Has Freqs AND Stokes
      !    real(kind=8), pointer :: freqs(:) => null()        ! (nchan*nstokes) = 0d0
      call r8(inhd64%freqs,outbuf(uvda_start+19+2*nlt),inhd64%nfreq)
      !    integer(kind=4), pointer :: stokes(:) => null()    ! (nchan*nstokes) = code_stoke
      call i4(inhd64%stokes,outbuf(uvda_start+19+2*nlt+2*inhd64%nfreq),inhd64%nfreq)
    else if (abs(inhd64%order).eq.abs(code_stok_chan)) then
      ! Only Stokes
      call i4(inhd64%stokes,outbuf(uvda_start+19+2*nlt), inhd64%nstokes)
    endif
    !
  else
    ! No UV Data section
    call i4(inhd64%uvda_words,outbuf(uvda_start),1)
    inhd64%tele_start = uvda_start + inhd64%uvda_words + 2
    call i4(inhd64%tele_start,outbuf(uvda_start+1),1)
  endif
  !
  !!Print *,'GIO_HD64_TO_BUFFER tele_start',tele_start
  tele_start = inhd64%tele_start
  if (inhd64%tele_words.ne.0) inhd64%tele_words = 2+inhd64%nteles*10
  call i4(inhd64%tele_words,outbuf(tele_start),1)
  inhd64%void_start = tele_start + inhd64%tele_words + 2
  call i4(inhd64%void_start,outbuf(tele_start+1),1)
  !
  if (inhd64%tele_words.ne.0) then
    call i4(inhd64%nteles,outbuf(tele_start+2),1)
    call i4(inhd64%magic,outbuf(tele_start+3),1)
    k = tele_start+4
    do i=1,inhd64%nteles
      call r8(inhd64%teles(i)%lon,outbuf(k),1)
      k = k+2
      call r8(inhd64%teles(i)%lat,outbuf(k),1)
      k = k+2
      call r4(inhd64%teles(i)%alt,outbuf(k),1)
      k = k+1
      call r4(inhd64%teles(i)%diam,outbuf(k),1)
      k = k+1
      call bytoby(inhd64%teles(i)%ctele,outbuf(k),12)
      k = k+3
      ! Skip padding
      k = k+1
    enddo
  endif
  !
end subroutine gio_hd64_to_buffer
!
function gio_gdfbuf(rname,iblock)
  use gio_image
  use gbl_message
  ! @ private
  !
  integer :: gio_gdfbuf
  character(len=*), intent(in) :: rname
  integer, intent(in) :: iblock
  character(len=40) :: mess
  !
  integer :: ier
  !
  ! Re-Allocate sufficient work space for GDFBIG here
  gio_gdfbuf = 0
  if (iblock.gt.mstbl) then
    if (mstbl.ne.0) deallocate(gdfbig,stat=ier)
    mstbl = 0
    allocate (gdfbig(lenbuf,iblock),stat=ier)
     if (ier.ne.0) then
       call gio_message(seve%e,rname,'GDFBIG allocation error')
       return
     else
       write(mess,'(A,I6)') 'GDFBIG re-allocation ',iblock
       call gio_message(seve%d,rname,mess)
     endif
     mstbl = iblock
  endif
  gio_gdfbuf = 1
  !
end function gio_gdfbuf
!
function gdf_check_nvisi(is,mess)
  use gio_image
  !---------------------------------------------------------------------
  ! @ public
  ! Return value:
  !  = 0 if visibility axis exists and Nvisi is equal to this axis, or
  !      if visibility axis does not exist
  !  < 0 if visibility axis exists and Nvisi is valid (lower than this
  !      axis: 0<=Nvisi<axis. Note 0 is still valid).
  !  > 0 if visibility axis exists but Nvisi is invalid (greater than
  !      this axis, or negative)
  ! A message is also set describing this status. The caller can use it
  ! or ignore it.
  !---------------------------------------------------------------------
  integer(kind=4) :: gdf_check_nvisi
  integer(kind=4),  intent(in)  :: is    ! Image slot
  character(len=*), intent(out) :: mess  ! Message in return
  ! Local
  integer(kind=index_length) :: nvisi,vdim
  !
  select case (gheads(is)%gil%type_gdf)
  case (code_gdf_uvt)
    vdim = gheads(is)%gil%dim(2)
  case (code_gdf_tuv)
    vdim = gheads(is)%gil%dim(1)
  case default
    ! No visibility axis
    gdf_check_nvisi = 0
    return
  end select
  !
  ! This is a UV table
  nvisi = gheads(is)%gil%nvisi
  if (nvisi.eq.vdim) then
    gdf_check_nvisi = 0  ! => Valid, nothing to say
  elseif (nvisi.lt.0) then
    gdf_check_nvisi = 1  ! => Invalid
    write(mess,'(A,I0,A)')  &
      'Number of visibilities (',nvisi,') is lower than 0'
  elseif (nvisi.lt.vdim) then
    gdf_check_nvisi = -1  ! => Valid, with a message
    write(mess,'(A,I0,A,I0,A)')  &
      'Number of visibilities (',nvisi, &
      ') is lower than the visibility axis (',vdim,')'
  else  ! if (nvisi.gt.vdim) then
    gdf_check_nvisi = 1  ! => Invalid
    write(mess,'(A,I0,A,I0,A)')  &
      'Number of visibilities (',nvisi, &
      ') is greater than the visibility axis (',vdim,')'
  endif
  !
end function gdf_check_nvisi
