subroutine maskon(line,error)
  use gildas_def
  use gbl_message
  use greg_dependencies_interfaces
  use greg_interfaces, except_this=>maskon
  use greg_kernel
  use greg_poly
  use greg_rg
  !---------------------------------------------------------------------
  ! @ private
  ! GreG Support routine for command
  !  GREG2\MASK [IN|OUT] [/BLANKING Bval]
  ! Mask the inside or the outside of a polygon
  !---------------------------------------------------------------------
  character(len=*), intent(in)  :: line   ! Input command line
  logical,          intent(out) :: error  ! Logical error flag
  ! Global
  include 'gbl_memory.inc'
  ! Local
  character(len=*), parameter :: rname='MASK'
  real(kind=4) :: blank
  logical :: in
  integer(kind=4) :: nc,ier,ikey
  character(len=6) :: argum,key
  real(kind=8) :: xconv(3),yconv(3)
  real(kind=4), pointer :: rgbuf(:,:)
  character(len=3), parameter :: inout(2) = (/ 'IN ','OUT' /)
  !
  error = .false.
  if (gpoly%ngon.le.2) then
    call greg_message(seve%e,rname,'No polygon defined')
    error = .true.
  endif
  if (rg%status.eq.code_pointer_null) then
    call greg_message(seve%e,rname,'No regular map loaded')
    error = .true.
  endif
  blank = cblank
  if (eblank.lt.0 .and. .not.sic_present(1,1)) then
    call greg_message(seve%e,rname,'No blanking value')
    error = .true.
  endif
  if (error) return
  call sic_r4 (line,1,1,blank,.false.,error)
  if (error) return
  !
  argum = 'OUT'
  call sic_ke(line,0,1,argum,nc,.false.,error)
  if (error) return
  call sic_ambigs(rname,argum,key,ikey,inout,2,error)
  if (error)  return
  in = key.eq.'IN'
  !
  if (rg%status.eq.code_pointer_associated) then
    ! 'rg%data' is currently used as pointer to data which is not
    ! under our control. Let's allocate our own data
    allocate(rgbuf(rg%nx,rg%ny),stat=ier)
    error = ier.ne.0
    if (error) return
    ! Duplicate data
    call r4tor4(rg%data,rgbuf,rg%nx*rg%ny)
    ! Point to our new buffer
    call reassociate_rgdata(rgbuf,rg%nx,rg%ny,error)
    if (error)  return
    rg%status = code_pointer_allocated  ! Steal the rgbuf allocation
  endif
  !
  xconv(:) = (/ rg%xref,rg%xval,rg%xinc /)
  yconv(:) = (/ rg%yref,rg%yval,rg%yinc /)
  call greg_poly2mask(blank,in,gpoly,rg%nx,rg%ny,xconv,yconv,rg%data)
end subroutine maskon
!
subroutine gr8_glmsk(poly,msk,nx,ny,xconv,yconv,box)
  use greg_dependencies_interfaces
  use greg_interfaces, except_this=>gr8_glmsk
  use greg_types
  !---------------------------------------------------------------------
  ! @ public
  !  Return a mask from the current polygon (L version)
  !---------------------------------------------------------------------
  type(polygon_t), intent(in)    :: poly        ! Polygon description
  integer(kind=4), intent(in)    :: nx,ny       ! Size of mask
  logical,         intent(out)   :: msk(nx,ny)  ! Mask to be set
  real(kind=8),    intent(in)    :: xconv(3)    ! Conversion along X
  real(kind=8),    intent(in)    :: yconv(3)    ! Conversion along Y
  integer(kind=4), intent(inout) :: box(4)      ! Mask boundary (xblc,yblc,xtrc,ytrc)
  ! Local
  real(kind=8) :: x,y,xinc,yinc,xval,yval,xref,yref
  integer(kind=4) :: i,j,imin,imax,jmin,jmax
  !
  if (poly%ngon.lt.3) then
    do j=1,ny
      do i=1,nx
        msk(i,j) = .false.
      enddo
    enddo
    do j=box(2),box(4)
      do i=box(1),box(3)
        msk(i,j) = .true.
      enddo
    enddo
    return
  endif
  !
  xref = xconv(1)
  xval = xconv(2)
  xinc = xconv(3)
  yref = yconv(1)
  yval = yconv(2)
  yinc = yconv(3)
  !
  ! Avoid exploring all the Map by finding IMIN,IMAX,JMIN,JMAX
  if (xinc.gt.0.) then
    imin = max (1, int((poly%xgon1-xval)/xinc+xref) )
    imax = min (nx,int((poly%xgon2-xval)/xinc+xref)+1 )
  else
    imin = max (1, int((poly%xgon2-xval)/xinc+xref) )
    imax = min (nx,int((poly%xgon1-xval)/xinc+xref)+1 )
  endif
  if (yinc.gt.0.) then
    jmin = max (1, int((poly%ygon1-yval)/yinc+yref) )
    jmax = min (ny,int((poly%ygon2-yval)/yinc+yref)+1 )
  else
    jmin = max (1, int((poly%ygon2-yval)/yinc+yref) )
    jmax = min (ny,int((poly%ygon1-yval)/yinc+yref)+1 )
  endif
  !
  do j=1,ny
    do i=1,nx
      msk(i,j) = .false.
    enddo
  enddo
  !
  ! Mask the inside
  do j=jmin,jmax
    do i=imin,imax
      x = (i-xref)*xinc+xval
      y = (j-yref)*yinc+yval
      msk(i,j) = greg_poly_inside(x,y,poly)
    enddo
  enddo
  box(1) = imin
  box(2) = jmin
  box(3) = imax
  box(4) = jmax
end subroutine gr8_glmsk
!
subroutine gr8_gimsk(poly,msk,nx,ny,xconv,yconv,box)
  use greg_dependencies_interfaces
  use greg_interfaces, except_this=>gr8_gimsk
  use greg_types
  !---------------------------------------------------------------------
  ! @ public
  !  Return a mask from the current polygon (I*4 version)
  !---------------------------------------------------------------------
  type(polygon_t), intent(in)    :: poly        ! Polygon description
  integer(kind=4), intent(in)    :: nx,ny       ! Size of mask
  integer(kind=4), intent(out)   :: msk(nx,ny)  ! Mask to be set
  real(kind=8),    intent(in)    :: xconv(3)    ! Conversion along X
  real(kind=8),    intent(in)    :: yconv(3)    ! Conversion along Y
  integer(kind=4), intent(inout) :: box(4)      ! Mask boundary (xblc,yblc,xtrc,ytrc)
  ! Local
  real(kind=8) :: x,y,xinc,yinc,xval,yval,xref,yref
  integer(kind=4) :: i,j,imin,imax,jmin,jmax
  !
  if (poly%ngon.lt.3) then
    do j=1,ny
      do i=1,nx
        msk(i,j) = 0
      enddo
    enddo
    do j=box(2),box(4)
      do i=box(1),box(3)
        msk(i,j) = 1
      enddo
    enddo
    return
  endif
  !
  xref = xconv(1)
  xval = xconv(2)
  xinc = xconv(3)
  yref = yconv(1)
  yval = yconv(2)
  yinc = yconv(3)
  !
  ! Avoid exploring all the Map by finding IMIN,IMAX,JMIN,JMAX
  if (xinc.gt.0.) then
    imin = max (1, int((poly%xgon1-xval)/xinc+xref) )
    imax = min (nx,int((poly%xgon2-xval)/xinc+xref)+1 )
  else
    imin = max (1, int((poly%xgon2-xval)/xinc+xref) )
    imax = min (nx,int((poly%xgon1-xval)/xinc+xref)+1 )
  endif
  if (yinc.gt.0.) then
    jmin = max (1, int((poly%ygon1-yval)/yinc+yref) )
    jmax = min (ny,int((poly%ygon2-yval)/yinc+yref)+1 )
  else
    jmin = max (1, int((poly%ygon2-yval)/yinc+yref) )
    jmax = min (ny,int((poly%ygon1-yval)/yinc+yref)+1 )
  endif
  !
  do j=1,ny
    do i=1,nx
      msk(i,j) = 0
    enddo
  enddo
  !
  ! Mask the inside
  do j=jmin,jmax
    do i=imin,imax
      x = (i-xref)*xinc+xval
      y = (j-yref)*yinc+yval
      if ( greg_poly_inside(x,y,poly) ) then
        msk(i,j) = 1
      endif
    enddo
  enddo
  box(1) = imin
  box(2) = jmin
  box(3) = imax
  box(4) = jmax
end subroutine gr8_gimsk
!
subroutine gr8_inout(poly,x,y,flag,n,where)
  use greg_dependencies_interfaces
  use greg_interfaces, except_this=>gr8_inout
  use greg_types
  !---------------------------------------------------------------------
  ! @ public
  !  Return 1 if inside, 0 if not
  !---------------------------------------------------------------------
  type(polygon_t), intent(in)    :: poly     ! Polygon description
  integer(kind=4), intent(in)    :: n        ! Number of points
  real(kind=8),    intent(in)    :: x(n)     ! X coordinates
  real(kind=8),    intent(in)    :: y(n)     ! Y coordinates
  real(kind=8),    intent(inout) :: flag(n)  ! Inside-out
  logical,         intent(in)    :: where    ! Test inside (.TRUE.) or Outside
  ! Local
  real(kind=8) :: xx,yy
  integer(kind=4) :: i
  !
  if (where) then
    do i=1,n
      xx = x(i)
      yy = y(i)
      if ( greg_poly_inside(xx,yy,poly) ) then
        flag(i) = 0.d0
      endif
    enddo
  else
    do i=1,n
      xx = x(i)
      yy = y(i)
      if ( .not.greg_poly_inside(xx,yy,poly) ) then
        flag(i) = 0.d0
      endif
    enddo
  endif
end subroutine gr8_inout
!
subroutine gr4_inout(poly,x,y,flag,n,where)
  use greg_dependencies_interfaces
  use greg_interfaces, except_this=>gr4_inout
  use greg_types
  !---------------------------------------------------------------------
  ! @ public
  !  Return 1 if inside, 0 if not
  !---------------------------------------------------------------------
  type(polygon_t), intent(in)    :: poly     ! Polygon description
  integer(kind=4), intent(in)    :: n        ! Number of points
  real(kind=4),    intent(in)    :: x(n)     ! X coordinates
  real(kind=4),    intent(in)    :: y(n)     ! Y coordinates
  real(kind=4),    intent(inout) :: flag(n)  ! Inside-out
  logical,         intent(in)    :: where    ! Test inside (.TRUE.) or Outside
  ! Local
  real(kind=8) :: xx,yy
  integer(kind=4) :: i
  !
  if (where) then
    do i=1,n
      xx = x(i)
      yy = y(i)
      if ( greg_poly_inside(xx,yy,poly) ) then
        flag(i) = 0.0
      endif
    enddo
  else
    do i=1,n
      xx = x(i)
      yy = y(i)
      if ( .not.greg_poly_inside(xx,yy,poly) ) then
        flag(i) = 0.0
      endif
    enddo
  endif
end subroutine gr4_inout
