subroutine init_pen(error)
  use gtv_dependencies_interfaces
  use gtv_interfaces, except_this=>init_pen
  use gtv_protocol
  use gtv_plot
  !---------------------------------------------------------------------
  ! @ private
  !  Initialize the look-up-table for coloured Pens
  !---------------------------------------------------------------------
  logical, intent(inout) :: error  ! Logical error flag
  !
  call load_pen(cw_output,gbl_pen,.false.,.false.,error)
  if (error)  return
  !
  ! Define the SIC variables related to pen LUT
  call sic_defstructure('LUT%PEN',.true.,error)
  if (error)  return
  call sic_def_real('LUT%PEN%HUE',       gbl_pen%hue, 1,gbl_pen%size,.false.,error)
  call sic_def_real('LUT%PEN%SATURATION',gbl_pen%sat, 1,gbl_pen%size,.false.,error)
  call sic_def_real('LUT%PEN%VALUE',     gbl_pen%val, 1,gbl_pen%size,.false.,error)
  call sic_def_real('LUT%PEN%RED',       gbl_pen%r,   1,gbl_pen%size,.false.,error)
  call sic_def_real('LUT%PEN%GREEN',     gbl_pen%g,   1,gbl_pen%size,.false.,error)
  call sic_def_real('LUT%PEN%BLUE',      gbl_pen%b,   1,gbl_pen%size,.false.,error)
  if (error)  return
  !
end subroutine init_pen
!
subroutine load_pen(out,pen,reuse,color,error)
  use gtv_interfaces, except_this=>load_pen
  use gtv_plot
  use gtv_types
  !---------------------------------------------------------------------
  ! @ private
  ! Load the appropriate LUT in the input 'pen' set of pen.
  !---------------------------------------------------------------------
  type(gt_display), intent(in)    :: out    !
  type(gt_lut),     intent(inout) :: pen    !
  logical,          intent(in)    :: reuse  ! Reuse current user's colormap?
  logical,          intent(in)    :: color  ! If not reuse, generate colors?
  logical,          intent(inout) :: error  !
  !
  error = .false.
  call gt_lut_alloc(pen,pen_size,error)
  if (error)  return
  !
  if (reuse .and. gbl_pen%size.gt.0) then
    pen = gbl_pen
    !
  elseif (color) then
    ! Use default color LUT
    call gt_lut_default(pen,pen%size)
    !
  elseif (out%background.eq.1) then
    ! Black LUT
    call gt_lut_rgb(pen,pen%size,1.,0.,1.,0.,1.,0.)
    !
  else
    ! White LUT
    call gt_lut_rgb(pen,pen%size,0.,1.,0.,1.,0.,1.)
  endif
  !
end subroutine load_pen
!
subroutine pen_lut(line,error)
  use gildas_def
  use gtv_dependencies_interfaces
  use gtv_interfaces, except_this=>pen_lut
  use gtv_plot
  use gtv_protocol
  !---------------------------------------------------------------------
  ! @ private
  ! Support routine for command:
  !   LUT [Argum] /PEN
  ! LOADS a color table read in a file written in free format,
  !   or defined by the Hue, Saturation, Value
  !   or Red Green Blue arrays,
  ! depending upon the current representation.
  !---------------------------------------------------------------------
  character(len=*), intent(in)    :: line   ! Input command line
  logical,          intent(inout) :: error  ! Logical error flag
  ! Local
  character(len=*), parameter :: rname='PENLUT'
  character(len=80) :: argum,arguml
  integer :: i
  integer :: nc
  !
  arguml = 'LUT'
  call sic_ch (line,0,1,arguml,nc,.false.,error)
  if (error)  return
  argum=arguml
  call sic_upper(argum(1:nc))
  !
  select case (argum)
  case('DEFAULT')
    call gt_lut_default(gbl_pen,gbl_pen%size)
    !
  case('COLOR')
    call gt_lut_color(gbl_pen,gbl_pen%size)
    !
  case('BLACK')
    call gt_lut_rgb(gbl_pen,gbl_pen%size,1.,0.,1.,0.,1.,0.)
    !
  case('WHITE')
    call gt_lut_rgb(gbl_pen,gbl_pen%size,0.,1.,0.,1.,0.,1.)
    !
  case('RED')
    call gt_lut_rgb(gbl_pen,gbl_pen%size,0.,1.,0.,0.,0.,0.)
    !
  case('GREEN')
    call gt_lut_rgb(gbl_pen,gbl_pen%size,0.,0.,0.,1.,0.,0.)
    !
  case('BLUE')
    call gt_lut_rgb(gbl_pen,gbl_pen%size,0.,0.,0.,0.,0.,1.)
    !
  case('YELLOW')
    call gt_lut_rgb(gbl_pen,gbl_pen%size,0.,1.,0.,1.,0.,0.)
    !
  case('CYAN')
    call gt_lut_rgb(gbl_pen,gbl_pen%size,0.,0.,0.,1.,0.,1.)
    !
  case('MAGENTA')
    call gt_lut_rgb(gbl_pen,gbl_pen%size,0.,1.,0.,0.,0.,1.)
    !
  case('NULL')
    call gt_lut_rgb(gbl_pen,gbl_pen%size,0.,0.,0.,0.,0.,0.)
    !
  case('LUT')
    if (lut_mode.eq.hsv_mode) then
      do i=1,gbl_pen%size
        gbl_pen%sat(i) = max(0.0,min(gbl_pen%sat(i),1.0))
        gbl_pen%val(i) = max(0.0,min(gbl_pen%val(i),1.0))
        gbl_pen%hue(i) = max(0.0,min(gbl_pen%hue(i),360.0))
        call hsv_to_rgb(gbl_pen%hue(i),gbl_pen%sat(i),gbl_pen%val(i),  &
                        gbl_pen%r(i),gbl_pen%g(i),gbl_pen%b(i))
      enddo
    else
      do i=1,gbl_pen%size
        gbl_pen%r(i) = max(0.0,min(1.0,gbl_pen%r(i)))
        gbl_pen%g(i) = max(0.0,min(1.0,gbl_pen%g(i)))
        gbl_pen%b(i) = max(0.0,min(1.0,gbl_pen%b(i)))
        call rgb_to_hsv(gbl_pen%r(i),gbl_pen%g(i),gbl_pen%b(i),  &
                        gbl_pen%hue(i),gbl_pen%sat(i),gbl_pen%val(i))
      enddo
    endif
    !
  case('?')
    call gt_lut_list(error)
    return  ! This was just a display, no action to perform on graphical window
    !
  case default
    ! Read from file, blanking is excluded
    call gt_lut_fromfile(arguml,gbl_pen,gbl_pen%size,error)
    if (error)  return
    !
  end select
  !
  ! /REVERSE reverts the PENLUT just loaded
  if (sic_present(3,0)) then
    call gt_lut_revert(gbl_pen,gbl_pen%size,error)
    if (error)  return
  endif
  !
end subroutine pen_lut
!
subroutine gtv_penlut(error)
  use gtv_interfaces, except_this=>gtv_penlut
  use gtv_tree
  use gtv_buffers
  use gtv_plot
  use gtv_graphic
  use gbl_message
  !---------------------------------------------------------------------
  ! @ private
  !  Defines the color pens Look Up Table in the METACODE
  ! ---
  !   Threads status: thread safe
  !---------------------------------------------------------------------
  logical, intent(inout) :: error  ! Logical error flag
  ! Local
  character(len=*), parameter :: rname='GTV_PENLUT'
  !
  call gtsegm('PENLUT',error)
  if (error)  return
  !
  call gt_penlut_segdata(error)
  ! if (error) close the segment
  !
  call gtsegm_close(error)  ! Thread-safe
  if (error)  return
  !
end subroutine gtv_penlut
!
subroutine gt_penlut_segdata(error)
  use gtv_interfaces, except_this=>gt_penlut_segdata
  use gtv_tree
  use gtv_buffers
  use gtv_plot
  use gtv_graphic
  use gbl_message
  !---------------------------------------------------------------------
  ! @ private
  !  Save the current pen color Look Up Table into the METACODE
  ! ---
  !   Threads status: thread safe
  !---------------------------------------------------------------------
  logical, intent(inout) :: error  ! Logical error flag
  ! Local
  character(len=*), parameter :: rname='GTV_PENLUT'
  integer(kind=4) :: ier
  !
  call gtv_open_segments_for_writing_from_main()
  !
  if (.not.associated(co_segment_data)) then
    allocate(co_segment%data,stat=ier)
    if (ier.ne.0) then
      call gtv_message(seve%e,rname,'Internal error: allocation failure (1)')
      error = .true.
      goto 10
    endif
    co_segment_data => co_segment%data
  else
    allocate(co_segment_data%nextdata,stat=ier)
    if (ier.ne.0) then
      call gtv_message(seve%e,rname,'Internal error: allocation failure (2)')
      error = .true.
      goto 10
    endif
    co_segment_data => co_segment_data%nextdata
  endif
  co_segment_data%nextdata => null()
  !
  ! Store the data
  call gt_lut_alloc(co_segment_data%lut,gbl_pen%size,error)
  if (error)  goto 10
  !
  ! Copy
  co_segment_data%kind = seg_pencol
  co_segment_data%lut%size = gbl_pen%size
  co_segment_data%lut%r(:) = gbl_pen%r(:)
  co_segment_data%lut%g(:) = gbl_pen%g(:)
  co_segment_data%lut%b(:) = gbl_pen%b(:)
  !
  ! Save the pen lut address for later use by polylines
  co_segment%head%lut => co_segment_data%lut
  !
10 continue
  !
  call gtv_close_segments_for_writing_from_main()
  !
end subroutine gt_penlut_segdata
!
subroutine gti_penlut(out,lut)
  use gtv_dependencies_interfaces
  use gtv_interfaces, except_this=>gti_penlut
  use gtv_tree
  use gtv_types
  use gtv_graphic
  use gtv_plot
  use gtv_protocol
  !---------------------------------------------------------------------
  ! @ private
  ! Defines the color pens Look Up Table on the DISPLAY
  !---------------------------------------------------------------------
  type(gt_display), intent(in) :: out  ! Input gt_display
  type(gt_lut),     intent(in) :: lut  !
  ! Local
  integer :: nn,i
  !
  if (.not.awake .or. error_condition) return
  !
  if (.not.lut_static)  return  ! The image LUT known by the device remains
    ! the global one (gbl_colormap). It should be a custom one only in the
    ! LUT STATIC case.
  !
  nn = min(gbl_pen%size,lut%size)
  if (nn.gt.0) then
    call r4tor4 (lut%r,gbl_pen%r,nn)
    call r4tor4 (lut%g,gbl_pen%g,nn)
    call r4tor4 (lut%b,gbl_pen%b,nn)
  endif
  !
  do i=1,gbl_pen%size
    call rgb_to_hsv(gbl_pen%r(i),gbl_pen%g(i),gbl_pen%b(i),  &
                    gbl_pen%hue(i),gbl_pen%sat(i),gbl_pen%val(i))
  enddo
  !
end subroutine gti_penlut
