Patch title: Release 81 bulk changes
Abstract:
File: /pliant/graphic/filter/escp2.pli
Key:
    Removed line
    Added line
   
# Copyright  Hubert Tonneau  hubert.tonneau@pliant.cx
#
# Writing this driver was possible only thanks to the great 
# Robert L Krawitz to gather and document detailed informati
# Epson inkjet printers.


gvar (Array Int 256) light_threshold light_removal big_thres
function init_dot
  for (var Int l) 0 255
# Copyright  Hubert Tonneau  hubert.tonneau@pliant.cx
#
# Writing this driver was possible only thanks to the great 
# Robert L Krawitz to gather and document detailed informati
# Epson inkjet printers.


gvar (Array Int 256) light_threshold light_removal big_thres
function init_dot
  for (var Int l) 0 255
    light_threshold l := cast (correct l/255 0.20)*255 Int
    light_threshold l := cast (correct l/255 0.25)*255 Int
    light_removal l := shunt l<=16 0 (cast ((l-16)/(255-16))
    light_removal l := shunt l<=16 0 (cast ((l-16)/(255-16))
    big_threshold l := shunt l<=128 0 (cast ((l-128)/(255-12
    big_threshold l := shunt l<=128 0 (cast ((l-128)/(255-128))^2*255 Int)
init_dot



method f open s options h -> status
  arg_rw ImageWriteFilterEpson f ; arg_rw Stream s ; arg Str
  # send printer setup commands, and copy the values we will
  if h:gamut:dimension<>1 and h:gamut:dimension<>3 and h:gam
    return failure:"Only black and white or CMY or CMYK imag
  var Int dpi_x dpi_y
  var Int heads jets dot_size dot_levels bpc space_x space_y
init_dot



method f open s options h -> status
  arg_rw ImageWriteFilterEpson f ; arg_rw Stream s ; arg Str
  # send printer setup commands, and copy the values we will
  if h:gamut:dimension<>1 and h:gamut:dimension<>3 and h:gam
    return failure:"Only black and white or CMY or CMYK imag
  var Int dpi_x dpi_y
  var Int heads jets dot_size dot_levels bpc space_x space_y
  var Float page_x page_y
  var Float page_x := undefined ; var Float page_y := undefined
  var Str command
  var Str model := options option "model" Str
  if model=""
    return failure:"You must specify the printer model"
  dpi_x := cast h:size_x/(h:x1-h:x0)*25.4 Int
  dpi_y := cast h:size_y/(h:y1-h:y0)*25.4 Int
  bpc := options option "escp2_bpc" Int 2
  if model="Epson 1280" or model="Epson 1290"
    heads := 3Fh
    jets := 48
    dot_size := 10h
    space_x := dpi_x\360
    space_y := dpi_y\120
    page_x := 13*25.4
    page_y := 19*25.4
    command := "margin4 zero_margin roll"
  eif model="Epson C80"
    heads := 0Fh
    jets := shunt h:gamut:dimension=1 180 60
    dot_size := 12h
    shift += 120 ; shift += 60 ; shift += 0 ; shift += 120
    space_x := dpi_x\360
    space_y := dpi_y\180
    page_x := 210
    page_y := 297
    command := ""
  eif model="Epson 2100" or model="Epson 2200"
    heads := 0BFh
    jets := 96
    dot_size := 10h
    space_x := dpi_x\360
    space_y := dpi_y\180
    page_x := 13*25.4
    page_y := 19*25.4
    command := "margin4 roll"
  var Str command
  var Str model := options option "model" Str
  if model=""
    return failure:"You must specify the printer model"
  dpi_x := cast h:size_x/(h:x1-h:x0)*25.4 Int
  dpi_y := cast h:size_y/(h:y1-h:y0)*25.4 Int
  bpc := options option "escp2_bpc" Int 2
  if model="Epson 1280" or model="Epson 1290"
    heads := 3Fh
    jets := 48
    dot_size := 10h
    space_x := dpi_x\360
    space_y := dpi_y\120
    page_x := 13*25.4
    page_y := 19*25.4
    command := "margin4 zero_margin roll"
  eif model="Epson C80"
    heads := 0Fh
    jets := shunt h:gamut:dimension=1 180 60
    dot_size := 12h
    shift += 120 ; shift += 60 ; shift += 0 ; shift += 120
    space_x := dpi_x\360
    space_y := dpi_y\180
    page_x := 210
    page_y := 297
    command := ""
  eif model="Epson 2100" or model="Epson 2200"
    heads := 0BFh
    jets := 96
    dot_size := 10h
    space_x := dpi_x\360
    space_y := dpi_y\180
    page_x := 13*25.4
    page_y := 19*25.4
    command := "margin4 roll"
  eif model="Epson 7600" or model="Epson 9600" or model="Epson 10600"
    heads := shunt model="Epson 10600" 03Fh 0BFh
    jets := 1
    dot_size := 10h
    space_x := 1
    space_y := 1
    command := "margin4 roll"
  else
    return (failure "'"+model+"' is not a valid printer mode
  dot_size := options option "escp2_dot_size" Int dot_size
  dot_levels := options option "escp2_dot_levels" Int (shunt
  if ((options (options option_position "page" options:len) 
    page_x := px ; page_y := py
  if not ((options (options option_position "offset" 0) opti
    offset_x := 0 ; offset_y := 0
  s writechars "[0][0][0]"
  s writechars escape+character:1+"@EJL 1284.4[lf]@EJL     [
  s writechars escape+"@"
  s writechars escape+"@"
  s writechars (escp2 "R" character:0+"REMOTE1")
  # s writechars (remote "PM" "[0][0]") # unknown
  s writechars (remote "SN" "[0][0]"+character:0) # paper 0=
  if (command option "duplex") and ( (options option "front"
    s writechars (remote "SN" "[0]"+character:7+character:(s
  if (command option "zero_margin")
    s writechars (remote "FP" "[0]"+character:B0h+character:
  # s writechars (remote "IR" "[0]"+character:3) # unkown
  if (command+" "+options option "roll")
    s writechars (remote "EX"  "[0][0][0][0]"+character:5+ch
  s writechars escape+"[0][0][0]"
  s writechars (escp2 "G" character:1) # graphic mode
  var Int base := 2880 ; var Int page_unit := 720
  s writechars (escp2 "U" (num1 base\page_unit)+(num1 base\d
  s writechars (escp2 "K" character:0+character:2) # color m
  s writechars (escp2 "i" character:0) # no microweave
  else
    return (failure "'"+model+"' is not a valid printer mode
  dot_size := options option "escp2_dot_size" Int dot_size
  dot_levels := options option "escp2_dot_levels" Int (shunt
  if ((options (options option_position "page" options:len) 
    page_x := px ; page_y := py
  if not ((options (options option_position "offset" 0) opti
    offset_x := 0 ; offset_y := 0
  s writechars "[0][0][0]"
  s writechars escape+character:1+"@EJL 1284.4[lf]@EJL     [
  s writechars escape+"@"
  s writechars escape+"@"
  s writechars (escp2 "R" character:0+"REMOTE1")
  # s writechars (remote "PM" "[0][0]") # unknown
  s writechars (remote "SN" "[0][0]"+character:0) # paper 0=
  if (command option "duplex") and ( (options option "front"
    s writechars (remote "SN" "[0]"+character:7+character:(s
  if (command option "zero_margin")
    s writechars (remote "FP" "[0]"+character:B0h+character:
  # s writechars (remote "IR" "[0]"+character:3) # unkown
  if (command+" "+options option "roll")
    s writechars (remote "EX"  "[0][0][0][0]"+character:5+ch
  s writechars escape+"[0][0][0]"
  s writechars (escp2 "G" character:1) # graphic mode
  var Int base := 2880 ; var Int page_unit := 720
  s writechars (escp2 "U" (num1 base\page_unit)+(num1 base\d
  s writechars (escp2 "K" character:0+character:2) # color m
  s writechars (escp2 "i" character:0) # no microweave
  s writechars escape+"U"+character:(shunt (options option "
  s writechars escape+"U"+character:(shunt (options option "unidirectional") 1 0) # unidirectional
  # s writechars (escp2 "s" character:2) # head speed: not r
  s writechars (escp2 "e" character:0+character:dot_size) # 
  s writechars (escp2 "D" num2:14400+(num1 14400\dpi_y*space
  s writechars (escp2 "C" num4:(cast page_y/25.4*page_unit I
  if (command option "margin4")
    s writechars (escp2 "c" num4:0+num4:(cast page_y/25.4*pa
  else
    s writechars (escp2 "c" num2:0+num2:(cast page_y/25.4*pa
  # s writechars (escp2 "s" character:2) # head speed: not r
  s writechars (escp2 "e" character:0+character:dot_size) # 
  s writechars (escp2 "D" num2:14400+(num1 14400\dpi_y*space
  s writechars (escp2 "C" num4:(cast page_y/25.4*page_unit I
  if (command option "margin4")
    s writechars (escp2 "c" num4:0+num4:(cast page_y/25.4*pa
  else
    s writechars (escp2 "c" num2:0+num2:(cast page_y/25.4*pa
  s writechars (escp2 "s" num4:(cast page_x/25.4*page_unit I
  if page_x=defined
    s writechars (escp2 "s" num4:(cast page_x/25.4*page_unit Int)+num4:(cast page_y/25.4*page_unit Int)) # page size
  f stream :> s
  f:input_line size := h size_y
  for (var Int y) 0 f:input_line:size-1
    f:input_line y := null
  f dim := h:gamut dimension
  f size_x := h size_x
  f size_y := h size_y
  f input_y := 0 ; f input_line_size := h line_size
  f space_x := space_x
  f space_y := space_y
  f heads := heads
  f jets := jets
  f dot_size := dot_size
  f dot_levels := dot_levels
  f bpc := bpc
  f shift := shift
  while f:shift:size<heads_count
    f shift += 0
  var Int sm := 0
  for (var Int i) 0 heads_count-1
    sm := max sm f:shift:i
  f delta := (jets+sm)*space_y 
  f:pass size := h:size_y+2*f:delta
  for (var Int y) 0 f:pass:size-1
    f:pass y := 0
  f output_line_size := (h:size_x\space_x*bpc+7)\8
  f output_lines := memory_allocate f:output_line_size*jets 
  f output_y := -(f delta)
  f left := cast offset_x/25.4*dpi_x Int
  f top := max (cast offset_y/25.4*dpi_y Int) f:delta
  f buffer := memory_allocate 2*f:output_line_size*jets+4 ad
  status := success



    while output_y<size_y
      if (pass output_y+delta)=2^space_x-1
        output_y -= 1
      while (pass output_y+delta)=2^space_x-1
        output_y += 1
      var Int p := 0
      while ((pass output_y+delta) .and. 2^p)<>0
        p += 1
      # 'first_line' and 'lines_count' is specifying the lim
      for (var Int h) 0 heads_count-1
        for (var Int j) 0 jets-1
          var Int y := output_y+(shift:h+j)*space_y
          if y>=0 and y<size_y and input_line:y=null
            # one input line is missing: wait until the inpu
            return success
      console "epson line " output_y "/" size_y "   [cr]"
      # everything is fine for the pass: let's send it to th
  f stream :> s
  f:input_line size := h size_y
  for (var Int y) 0 f:input_line:size-1
    f:input_line y := null
  f dim := h:gamut dimension
  f size_x := h size_x
  f size_y := h size_y
  f input_y := 0 ; f input_line_size := h line_size
  f space_x := space_x
  f space_y := space_y
  f heads := heads
  f jets := jets
  f dot_size := dot_size
  f dot_levels := dot_levels
  f bpc := bpc
  f shift := shift
  while f:shift:size<heads_count
    f shift += 0
  var Int sm := 0
  for (var Int i) 0 heads_count-1
    sm := max sm f:shift:i
  f delta := (jets+sm)*space_y 
  f:pass size := h:size_y+2*f:delta
  for (var Int y) 0 f:pass:size-1
    f:pass y := 0
  f output_line_size := (h:size_x\space_x*bpc+7)\8
  f output_lines := memory_allocate f:output_line_size*jets 
  f output_y := -(f delta)
  f left := cast offset_x/25.4*dpi_x Int
  f top := max (cast offset_y/25.4*dpi_y Int) f:delta
  f buffer := memory_allocate 2*f:output_line_size*jets+4 ad
  status := success



    while output_y<size_y
      if (pass output_y+delta)=2^space_x-1
        output_y -= 1
      while (pass output_y+delta)=2^space_x-1
        output_y += 1
      var Int p := 0
      while ((pass output_y+delta) .and. 2^p)<>0
        p += 1
      # 'first_line' and 'lines_count' is specifying the lim
      for (var Int h) 0 heads_count-1
        for (var Int j) 0 jets-1
          var Int y := output_y+(shift:h+j)*space_y
          if y>=0 and y<size_y and input_line:y=null
            # one input line is missing: wait until the inpu
            return success
      console "epson line " output_y "/" size_y "   [cr]"
      # everything is fine for the pass: let's send it to th
      s writechars (escp2 "V" (num4 top+output_y))
      var CBool vpos := true
      for (var Int h) 0 heads_count-1
        var Int first_line := output_y+shift:h*space_y
        var Int lines_count := min (size_y-first_line+space_
        if (heads .and. 2^h)<>0 and lines_count>0 and (shunt
      for (var Int h) 0 heads_count-1
        var Int first_line := output_y+shift:h*space_y
        var Int lines_count := min (size_y-first_line+space_
        if (heads .and. 2^h)<>0 and lines_count>0 and (shunt
          s writechars (escp2 "$" (num4 left+p))
          s writechars escape+"i"+character:(shunt h=0 2 h=1
          memory_clear f:output_lines output_line_size*lines
          memory_clear f:output_lines output_line_size*lines_count ; var CBool some := false
          for (var Int j) 0 lines_count-1
            var Int y := first_line+j*space_y
            if y>=0
              var Address src := input_line:y translate uInt
              for (var Int x) p size_x-1 step space_x
                var Int l := src map uInt8
                # handle pixel 'x' 'y' on head 'h' , which l
                if l<>0
                  var Int d # 'd' will be the dot size
                  if noise_divisor>0
                    memory_random addressof:(var Int r) Int:
                    l += r % (((min l 255-l)+(noise_divisor-
                  head_rotation:h apply x y (var Int rx) (va
                  var Int t := dither_matrix cell rx ry # 't
                  if exists:generator
                    generator_prototype x y h d l generator
                    if l<=t
                      d := 0
                  else
                    var CBool light := (heads .and. 2^(4+(h%
                    var CBool big := dot_levels>1 and big_th
                    var CBool small := l>t and not light and
                    if h<4
                      d := shunt big 3 small 1 0
                    else
                      d := shunt light 1 0
                  if d<>0
                    output_lines map uInt8 j*output_line_siz
          for (var Int j) 0 lines_count-1
            var Int y := first_line+j*space_y
            if y>=0
              var Address src := input_line:y translate uInt
              for (var Int x) p size_x-1 step space_x
                var Int l := src map uInt8
                # handle pixel 'x' 'y' on head 'h' , which l
                if l<>0
                  var Int d # 'd' will be the dot size
                  if noise_divisor>0
                    memory_random addressof:(var Int r) Int:
                    l += r % (((min l 255-l)+(noise_divisor-
                  head_rotation:h apply x y (var Int rx) (va
                  var Int t := dither_matrix cell rx ry # 't
                  if exists:generator
                    generator_prototype x y h d l generator
                    if l<=t
                      d := 0
                  else
                    var CBool light := (heads .and. 2^(4+(h%
                    var CBool big := dot_levels>1 and big_th
                    var CBool small := l>t and not light and
                    if h<4
                      d := shunt big 3 small 1 0
                    else
                      d := shunt light 1 0
                  if d<>0
                    output_lines map uInt8 j*output_line_siz
                    some := true
                src := src translate uInt8 space_x*dim
                src := src translate uInt8 space_x*dim
          if packbits
            var Int csize := packbits_encode output_lines bu
            s raw_write buffer csize
          else
            s raw_write output_lines lines_count*output_line
          s writechars "[cr]"
          if some
            if vpos
              s writechars (escp2 "V" (num4 top+output_y))
              vpos := false
            s writechars (escp2 "$" (num4 left+p))
            s writechars escape+"i"+character:(shunt h=0 2 h=1 1 h=2 4 h=3 0 h=4 18 h=5 17 h=6 20 h=7 16 0)+character:(shunt packbits 1 0)+character:bpc+num2:output_line_size+num2:lines_count
            if packbits
              var Int csize := packbits_encode output_lines buffer lines_count*output_line_size
              s raw_write buffer csize
            else
              s raw_write output_lines lines_count*output_line_size
            s writechars "[cr]"
      # ajust the number of pass already done for each line,
      for (var Int j) 0 jets-1
        var Int y := output_y+j*space_y
        check ((pass y+delta) .and. 2^p)=0
        pass y+delta += 2^p
        if (pass y+delta)=2^space_x-1 and y>=0 and y<size_y
          memory_free f:input_line:y
          f:input_line y := cast -1 Address
      output_y += jets\space_x
  status := success



      # ajust the number of pass already done for each line,
      for (var Int j) 0 jets-1
        var Int y := output_y+j*space_y
        check ((pass y+delta) .and. 2^p)=0
        pass y+delta += 2^p
        if (pass y+delta)=2^space_x-1 and y>=0 and y<size_y
          memory_free f:input_line:y
          f:input_line y := cast -1 Address
      output_y += jets\space_x
  status := success