Patch title: Release 81 bulk changes
Abstract:
File: /pliant/protocol/lpr/spool.pli
Key:
    Removed line
    Added line
module "/pliant/language/unsafe.pli"
module "/pliant/language/stream.pli"
module "/pliant/language/stream/pipe.pli"
module "/pliant/admin/file.pli"
module "/pliant/admin/execute.pli"
module "/pliant/fullpliant/this_computer.pli"

module "database.pli"
module "/pliant/language/schedule/namedsem.pli"
module "/pliant/language/schedule/daemon.pli"

module "/pliant/graphic/filter/io.pli"
module "/pliant/graphic/image/lazy.pli"
module "/pliant/graphic/image/resampling.pli"
module "/pliant/graphic/image/antialiasing.pli"
module "/pliant/graphic/image/convert.pli"
module "/pliant/graphic/image/sharpening.pli"
module "/pliant/graphic/image/correct.pli"
module "/pliant/graphic/color/gamut.pli"
module "/pliant/math/curve/database.pli"

module "/pliant/protocol/ftp/client.pli"
module "/pliant/protocol/lpr/client.pli"
module "device.pli"
module "embedded.pli"


function lpr_print image options printer -> status
  oarg_rw ImagePrototype image ; arg Str options ; arg Data:LprQueue printer ; arg ExtendedStatus status
  var Link:ImageAntiAliasing aa
  if printer:antialiasing<>1
    aa :> new ImageAntiAliasing
    status := aa bind image printer:antialiasing
    if status=failure
      return
  else
    aa :> addressof:image map ImageAntiAliasing
  var Link:ImageConvert conv
  if printer:gamut<>""
    conv :> new ImageConvert
    status := conv bind aa (color_gamut printer:gamut) "grid_steps "+(string printer:grid_steps)
    if status=failure
      return
  else
    conv :> addressof:aa map ImageConvert
  var Link:ImageSharpening sharpen
  if printer:sharpening=defined
    sharpen :> new ImageSharpening
    status := sharpen bind conv printer:sharpening
    if status=failure
      return
  else
    sharpen :> addressof:conv map ImageSharpening
  var Link:ImageCorrect corr :> new ImageCorrect
  if printer:middle=defined or printer:limit=defined
    corr :> new ImageCorrect
    status := corr bind sharpen "exposure "+(string printer:middle)+" multiply "+(string printer:limit)
  else
    corr :> addressof:sharpen map ImageCorrect
  var Str opt := "filter "+(string "."+printer:driver)+" model "+(string printer:model)+" notmp "+printer:options+" timeout "+(string printer:timeout)
  if ((options (options option_position "offset" 0) options:len) parse word:"offset" (var Float offset_x) (var Float offset_y) any)
    if not ((opt (opt option_position "offset" 0) opt:len) parse word:"offset" (var Float base_x) (var Float base_y) any)
      base_x := 0 ; base_y := 0
    opt := "offset "+(string base_x+offset_x)+" "+(string base_y+offset_y)+" "+opt
  lpr_device_init printer:device
  if printer:once
    status := corr save printer:device opt
    if status=failure
      return
  else
    var Str temp2 := file_temporary 
    status := corr save temp2 opt
    if status=failure
      file_delete temp2
      return
    part send "sending file to printer"
      status := file_copy temp2 (string printer:device)+opt reduced
    file_delete temp2
    if status=failure
      return
  status := success


function lpr_print filename format printer -> status
  arg Str filename format ; arg Data:LprQueue printer ; arg ExtendedStatus status
  lpr_device_init printer:device
  if format="PostScript" and printer:filter<>""
  if format="PostScript" and printer:driver<>""
    var Str temp := replace file_temporary "file:/" "embedded:/"
    file_copy filename temp
    part print "print job on "+keyof:printer
      stream_pipe (var Str in_pipe) (var Str out_pipe)
      thread
        execute "gs -sDEVICE=ppmraw -r"+(string printer:resolution_x*printer:antialiasing)+"x"+(string printer:resolution_y*printer:antialiasing)+" -sOutputFile=- -q -dNOPAUSE -dSAFER "+file_os_name:(replace temp "embedded:/" "file:/")+" -c quit" root "embedded:/" path "embedded:/" output out_pipe
      var Link:Stream s :> new Stream
      s open in_pipe in+safe
      while not s:atend
        var Link:ImageLazy lazy :> new ImageLazy
        status := lazy bind s "filter [dq].ppm[dq] resolution "+(string printer:resolution_x)+" "+(string printer:resolution_y)
        if lazy=failure
          leave print
        # console "inital image is " lazy:size_x " x " lazy:size_y " pixels and " (string lazy:x1-lazy:x0 "fixed 1") " x "  (string lazy:y1-lazy:y0 "fixed 1") " mm" eol
        var Link:ImageResampling rs
        if printer:margin_left<>0 or printer:margin_top<>0 or printer:margin_right<>0 or printer:margin_bottom<>0
          var Int ix0 := lazy index_x printer:margin_left
          var Float fx0 := lazy:x0+(lazy:x1-lazy:x0)*ix0/lazy:size_x
          var Int iy0 := lazy index_y printer:margin_left
          var Float fy0 := lazy:y0+(lazy:y1-lazy:y0)*iy0/lazy:size_y
          var Int ix1 := lazy index_x printer:size_x-printer:margin_right
          var Float fx1 := lazy:x0+(lazy:x1-lazy:x0)*ix1/lazy:size_x
          var Int iy1 := lazy index_y printer:size_y-printer:margin_bottom
          var Float fy1 := lazy:y0+(lazy:y1-lazy:y0)*iy1/lazy:size_y
          var Link:ImageResampling rs :> new ImageResampling
          status := rs bind lazy fx0 fy0 fx1 fy1 ix1-ix0 iy1-iy0
          if status=failure
            leave print
        else
          rs :> addressof:lazy map ImageResampling
        var Link:ImageAntiAliasing aa
        if printer:antialiasing<>1
          aa :> new ImageAntiAliasing
          status := aa bind rs printer:antialiasing
          if status=failure
            leave print
        else
          aa :> addressof:rs map ImageAntiAliasing
        var Link:ImageConvert conv
        if printer:gamut<>""
          conv :> new ImageConvert
          status := conv bind aa (color_gamut printer:gamut) "grid_steps "+(string printer:grid_steps)
          if status=failure
            leave print
        else
          conv :> addressof:aa map ImageConvert
        var Link:ImageSharpening sharpen
        if printer:sharpening=defined
          sharpen :> new ImageSharpening
          status := sharpen bind conv printer:sharpening
          if status=failure
            leave print
        else
          sharpen :> addressof:conv map ImageSharpening
        var Link:ImageCorrect corr :> new ImageCorrect
        if printer:middle=defined or printer:limit=defined
          corr :> new ImageCorrect
          status := corr bind sharpen "exposure "+(string printer:middle)+" multiply "+(string printer:limit)
        else
          corr :> addressof:sharpen map ImageCorrect
        # console "final image is " corr:size_x " x " corr:size_y " pixels and " (string corr:x1-corr:x0 "fixed 1") " x "  (string corr:y1-corr:y0 "fixed 1") " mm" eol
        if printer:once
          status := corr save printer:device "filter "+(string printer:filter)+" notmp "+printer:options
          if status=failure
            leave print
        else
          var Str temp2 := file_temporary 
          status := corr save temp2 "filter "+(string printer:filter)+" "+printer:options
          if status=failure
            file_delete temp2
            leave print
          status := file_copy temp2 (string printer:device)+" "+printer:options reduced
          file_delete temp2
          if status=failure
            leave print
        status := lpr_print rs "" printer
        if status=failure
          leave print
        lazy read 0 lazy:size_y-1 1 addressof:(var ColorBuffer drop_pixel)
      status := success
    file_delete temp
  else
    status := file_copy filename (string printer:device)+" "+printer:options reduced
    lpr_device_init printer:device
    status := file_copy filename (string printer:device)+" "+printer:options+" timeout "+(string printer:timeout) reduced


function lpr_spool
  daemon "print spooler"
    while not daemon_emergency
      lpr_embedded_migrate "embedded:/"
      var DateTime start := datetime
      each p this_computer:env:"printer"
        var Str queue := keyof p
        var Str printer := p "printer"
        part print_one_queue
          if (lpr_printer_sem nowait_request printer)
            var Array:FileInfo files := file_list "data:/pliant/spool/"+queue+"/" standard
            for (var Int i) 0 files:size-1
              if files:i:extension=".lpr"
                var Str job := files:i:stripped_name
                var (Link Database:LprMeta) db :> new Database:LprMeta
                db load "data:/pliant/spool/"+queue+"/"+job+".pdb"
                if db:data:status=""
                  thread
                    db:data status := "printing"
                    db store
                    var ExtendedStatus status := lpr_print "data:/pliant/spool/"+queue+"/"+job+".lpr" db:data:format (this_computer:env:"printer":queue pmap "" LprQueue)
                    if status=success
                      file_delete "data:/pliant/spool/"+queue+"/"+job+".lpr"
                      file_delete "data:/pliant/spool/"+queue+"/"+job+".pdb"
                    else
                      db:data status := "error"
                      db:data error := status message
                      db store
                    lpr_printer_sem release printer
                  leave print_one_queue
            lpr_printer_sem release printer
      plugin sleep
        daemon_sleep (min (max (cast 100*(datetime:seconds-start:seconds) Int) 2) 30)

export lpr_print lpr_spool