subroutine read_all(fits,error,eot)
  use gildas_def
  use gbl_format
  use gbl_message
  use image_def
  use gsys_types
  use gio_dependencies_interfaces
  use gio_interfaces, except_this=>read_all
  use gio_fitsdef
  !---------------------------------------------------------------------
  ! @ private
  ! Read all the input FITS image
  !
  ! Should be re-written by using a block mode operation, with say a
  ! few Mbyte buffer, or even less...
  ! Slot re-shaping can be used for this
  ! Extrema should be carried on through, not in a separate pass...
  !---------------------------------------------------------------------
  type(gildas), intent(inout) :: fits   !
  logical,      intent(out)   :: error  ! Error flag
  logical,      intent(inout) :: eot    ! End of Tape flag
  ! Global
  include 'gbl_memory.inc'
  ! Local
  integer(kind=size_length) :: nfill
  integer :: i
  integer(kind=address_length) :: ip
  type(time_t) :: time
  integer(kind=index_length) :: large_dim, block_num, ibl, old_dims(gdf_maxdims)
  integer(kind=size_length) :: imin, imax, jmin, jmax, data_size, nblank
  real(4) :: rmin, rmax, amin, amax
  integer :: old_ndim, ier, block_factor
  real, allocatable :: mydata(:)
  ! This will be removed at some point, once debugging is fool-proof
  logical, save :: mode_all=.false.
  integer(kind=8) :: ilong
  character(len=message_length) :: mess
  character(len=*), parameter :: rname= 'FITS_GILDAS'
  !
  error = .false.
  !
  ! Write the sections
  !
  ! Read the data
  if (fits%loca%islo.ne.0) then
    call gio_fris (fits%loca%islo,error)
    fits%loca%islo = 0
  endif
  fits%loca%size = 1
  do i=1,gdf_maxdims
    if (fits%gil%dim(i).le.0) fits%gil%dim(i)=1
    fits%loca%size = fits%loca%size*fits%gil%dim(i)
  enddo
  !
  ! Only Real*4 images supported
  call gio_geis (fits%loca%islo,error)
  fits%gil%blan_words = 2
  fits%gil%extr_words = 0  ! Set in close_gdf
  call gio_write_header(fits,fits%loca%islo,error)
  fits%char%type = 'GILDAS_IMAGE'
  fits%gil%form = fmt_r4
  if (.not.error)  then
    call gio_cris(fits%loca%islo,fits%char%type, &
    &   fits%file,fits%gil%form,fits%loca%size,error)
  endif
  if (error) then
    call gio_message(seve%e,rname,'Image '//trim(fits%file)//' not created')
    return
  endif
  !
  ! Make sure the FITS file is at the right position
  nfill = 0
  call gfits_flush_data(error)
  if (error) return
  !
  fits%blc = 0
  fits%trc = 0
  !
  if (mode_all) then
    !
    ! Old way, all at once, memory hungry...
    call gio_gems (fits%loca%mslo,fits%loca%islo,fits%blc,fits%trc,fits%loca%addr,fits%gil%form,error)
    if (error) return
    !
    ip = gag_pointer(fits%loca%addr,memory)
    call read_allmap(fd,memory(ip),fits%loca%size,nfill,fits%gil%bval,error)
    if (nfill.lt.fits%loca%size) then
      call gio_message(seve%w,rname,'FITS data file is incomplete')
    endif
    !
    call close_gdf(fd,fits,memory(ip),error)
  else
    !
    ! Read by block, extrema not set, but memory saving...
    old_ndim = fits%gil%ndim
    old_dims = fits%gil%dim
    !
    ! Decompose in large blocks
    fits%gil%ndim = 2
    fits%gil%dim(2) = fits%loca%size / fits%gil%dim(1)
    large_dim = max(fits%gil%dim(1),fits%gil%dim(2))
    block_num = fits%loca%size / large_dim 
    fits%gil%dim = 1
    fits%gil%dim(1) = large_dim
    fits%gil%dim(2) = block_num
    fits%blc(1) = 1
    fits%trc(1) = fits%gil%dim(1)     
    !
    block_factor = max((256*256)/large_dim,1)
    allocate (mydata(large_dim*block_factor),stat=ier)
    !
    fd%nb = 2881  ! Initialize FITS byte counter
    !
    call gtime_init(time,block_num/block_factor,error)
    if (error)  goto 100
    !
    rmin = huge(1.0)
    rmax = -huge(1.0)
    nblank = 0
    !
    do ibl = 1, block_num, block_factor
      call gtime_current(time)
      !
      fits%blc(2) = ibl
      fits%trc(2) = min(ibl+block_factor-1,fits%gil%dim(2))
      data_size = (fits%trc(2)-fits%blc(2)+1)*large_dim
      mydata = 0.0
      call gfits_getreal(fd,data_size, mydata, fd%bscal, fd%bzero, error)
      if (error) goto 100 
      !
      ! Patch NaN or bval
      call fitscube2gdf_patch_bval(fd,fits,mydata,data_size,nblank,error)
      if (error)  goto 100
      !
      ! Extrema
      call gr4_extrema (data_size,mydata,     &
                       fits%gil%bval, fits%gil%eval,  &
                       amin, amax, imin, imax)
      if (amin.lt.rmin) then
        rmin = amin
        jmin = (ibl-1)*fits%gil%dim(1) + imin
      endif
      if (amax.gt.rmax) then
        rmax = amax
        jmax = (ibl-1)*fits%gil%dim(1) + imax
      endif
      !
      ! Write the current section
      call gdf_write_data(fits,mydata,error)
      if (error) goto 100
      !
    enddo
    !
    if (nblank.eq.0) then
      fits%gil%eval = -1.0
      call gio_message(seve%d,rname,'No blank data in FITS file')
    else
      write(mess,'(A,I0,A)') 'Patched ',nblank,' blank data'
      call gio_message(seve%d,rname,mess)
    endif
    !
    fits%gil%dim = old_dims
    fits%gil%ndim = old_ndim
    !
    ! Update extrema here if needed
    fits%gil%rmin = rmin
    fits%gil%rmax = rmax
    ilong = jmin
    call gdf_index_to_where(ilong,fits%gil%ndim,fits%gil%dim,fits%gil%minloc)
    ilong = jmax
    call gdf_index_to_where(ilong,fits%gil%ndim,fits%gil%dim,fits%gil%maxloc)
    fits%gil%extr_words = def_extr_words
    !
    call gdf_update_header(fits,error)
    !
    ! Close image
    call gdf_close_image(fits,error)
    !
    ! Restore shape of array
100 continue
    fits%gil%ndim = old_ndim
    fits%gil%dim = old_dims
    deallocate (mydata)
  endif  
  !
end subroutine read_all
!
subroutine close_gdf(fd,fits,z,error)
  use gbl_message
  use image_def
  use gfits_types
  use gio_interfaces
  !---------------------------------------------------------------------
  ! @ no-interface
  ! Flush the GILDAS image.
  !---------------------------------------------------------------------
  type(gfits_hdesc_t), intent(in)    :: fd     !
  type(gildas),        intent(inout) :: fits   !
  real(kind=4),        intent(inout) :: z(*)   !
  logical,             intent(inout) :: error  !
  ! Local
  logical :: err,update
  integer(kind=size_length) :: nblank
  !
  err = .false.
  nblank = 0
  call fitscube2gdf_patch_bval(fd,fits,z,fits%loca%size,nblank,err)
  if (err)  error = .true.
  !
  update = .false.
  if (fits%gil%blan_words.ne.0 .and. nblank.eq.0) then
    fits%gil%eval = -1.0
    update = .true.
  endif
  if (fits%gil%extr_words.eq.0) then
    call gio_message(seve%i,'FITS','Computing extrema...')
    call gdf_get_extrema(fits,err)
    update = .true.
  endif
  if (update)  call gdf_update_header(fits,err)
  !
  call gdf_close_image(fits,err)
  if (err) error = .true.
  !
end subroutine close_gdf
!
subroutine read_sub(fits,error,eot,blc,trc)
  use gildas_def
  use gbl_format
  use gbl_message
  use image_def
  use gio_dependencies_interfaces
  use gio_interfaces, except_this=>read_sub
  use gio_params
  use gio_fitsdef
  !---------------------------------------------------------------------
  ! @ private
  ! FITS  Support routine for command
  !
  !       READ [/BLC Nx1 Nx2 Nx3 Nx4] [/TRC Ny1 Ny2 Ny3 Ny4]
  ! Arguments :
  !       ERROR   L       Logical error flag      Output
  !---------------------------------------------------------------------
  type(gildas),          intent(inout) :: fits    !
  logical,               intent(out)   :: error   ! Error flag
  logical,               intent(inout) :: eot     ! End of Tape flag
  integer(index_length), intent(in)    :: blc(:)  !
  integer(index_length), intent(in)    :: trc(:)  !
  ! Global
  include 'gbl_memory.inc'
  ! Local
  character(len=*), parameter :: rname='READ'
  integer :: i
  integer(kind=index_length) :: gdim(gdf_maxdims),gblc(gdf_maxdims),gtrc(gdf_maxdims)
  integer(kind=address_length) :: ip
  character(len=message_length) :: mess
  !
  ! Clip within the map
  gblc = blc
  gtrc = trc
  do i=1,gdf_maxdims
    if (gblc(i).le.0) then
      if (gblc(i).lt.0) then
        write(mess,101) i
        call gio_message(seve%w,rname,mess)
      endif
      gblc(i) = 1
    elseif (gblc(i).gt.fits%gil%dim(i)) then
      write(mess,102) i,fits%gil%dim(i)
      call gio_message(seve%w,rname,mess)
      gblc(i) = fits%gil%dim(i)
    endif
    if (gtrc(i).eq.0) then
      gtrc(i) = fits%gil%dim(i)
    elseif (gtrc(i).lt.gblc(i)) then
      write(mess,103) i,i
      call gio_message(seve%e,rname,mess)
      error = .true.
      return
    elseif (gtrc(i).gt.fits%gil%dim(i)) then
      write(mess,104) i,fits%gil%dim(i)
      call gio_message(seve%w,rname,mess)
      gtrc(i) = fits%gil%dim(i)
    endif
  enddo
  !
  ! Change the header by the appropriate pixel displacements
  fits%gil%convert(1,1:gdf_maxdims) = fits%gil%convert(1,1:gdf_maxdims)-gblc(1:gdf_maxdims) 
  ! Change the size
  do i=1,gdf_maxdims
    gdim(i) = fits%gil%dim(i)
    fits%gil%dim(i) = gtrc(i)-gblc(i)+1
  enddo
  !
  ! Read the data
  error = .false.
  if (fits%loca%islo.ne.0) then
    call gio_fris (fits%loca%islo,error)
    fits%loca%islo = 0
  endif
  fits%loca%size = 1
  do i=1,gdf_maxdims
    if (fits%gil%dim(i).le.0) fits%gil%dim(i)=1
    fits%loca%size = fits%loca%size*fits%gil%dim(i)
  enddo
  call gio_geis (fits%loca%islo,error)
  call gio_write_header(fits,fits%loca%islo,error)
  fits%char%type = 'GILDAS_IMAGE'
  fits%gil%form = fmt_r4
  if (.not.error)  then
    call gio_cris (fits%loca%islo,fits%char%type, &
    & fits%file,fits%gil%form,fits%loca%size,error)
  endif
  if (error) then
    call gio_message(seve%e,rname,'Image not created')
    return
  endif
  call gio_gems (fits%loca%mslo,fits%loca%islo,fits%blc,fits%trc,fits%loca%addr,fits%gil%form,error)
  if (error) return
  !
  ! Make sure the FITS file is at the right position
  call gfits_flush_data(error)
  if (error) return
  !
  ! Load map into virtual memory
  ip = gag_pointer(fits%loca%addr,memory)
  call read_subset(fd,memory(ip),fits%loca%size,gdim,gblc,gtrc,error,fits%gil%bval)
  !
  call close_gdf(fd,fits,memory(ip),error)
  !
101 format('BLC(',i1,') is negative, 1 used instead')
102 format('BLC(',i1,') is greater than image dimension ',i6,' truncated')
103 format('TRC(',i1,') is smaller than BLC(',i1,')')
104 format('TRC(',i1,') is greater than image dimension ',i6,' truncated')
end subroutine read_sub
