Patch title: Release 91 bulk changes
Abstract:
File: /graphic/vfilter/pdf.pli
Key:
    Removed line
    Added line
   
module "/pliant/language/compiler.pli"
module "/pliant/language/stream.pli"
module "/pliant/language/stream/filesystembase.pli"
module "/pliant/language/stream/count.pli"
module "/pliant/admin/file.pli"
module "/pliant/math/transform.pli"
module "/pliant/math/curve.pli"
module "/pliant/math/matrix.pli"
module "/pliant/graphic/draw/prototype.pli"
module "/pliant/language/compiler.pli"
module "/pliant/language/stream.pli"
module "/pliant/language/stream/filesystembase.pli"
module "/pliant/language/stream/count.pli"
module "/pliant/admin/file.pli"
module "/pliant/math/transform.pli"
module "/pliant/math/curve.pli"
module "/pliant/math/matrix.pli"
module "/pliant/graphic/draw/prototype.pli"
module "/pliant/graphic/draw/displaylist.pli"
module "/pliant/graphic/vector/font.pli"
module "/pliant/graphic/vector/freetype.pli"
module "/pliant/graphic/vector/stroke.pli"
module "/pliant/graphic/color/gamut.pli"
module "/pliant/graphic/image/packed.pli"
module "/pliant/graphic/misc/bytes.pli"
module "/pliant/graphic/misc/float.pli"
module "/pliant/language/data/cache.pli"
module "/pliant/language/compiler/type/inherit.pli"
module "/pliant/language/data/id.pli"
module "/pliant/graphic/filter/prototype.pli"
module "/pliant/graphic/filter/jpeg.pli"
module "prototype.pli"


constant debug false
module "/pliant/graphic/vector/font.pli"
module "/pliant/graphic/vector/freetype.pli"
module "/pliant/graphic/vector/stroke.pli"
module "/pliant/graphic/color/gamut.pli"
module "/pliant/graphic/image/packed.pli"
module "/pliant/graphic/misc/bytes.pli"
module "/pliant/graphic/misc/float.pli"
module "/pliant/language/data/cache.pli"
module "/pliant/language/compiler/type/inherit.pli"
module "/pliant/language/data/id.pli"
module "/pliant/graphic/filter/prototype.pli"
module "/pliant/graphic/filter/jpeg.pli"
module "prototype.pli"


constant debug false
constant message_debug false



type PDFObject
  field Intn offset
  field Arrow content
  field Intn seek
  field Str cache_id



type PDFObject
  field Intn offset
  field Arrow content
  field Intn seek
  field Str cache_id
  field Arrow attached

type PDFReader
  field Link:Stream raw_stream stream

type PDFReader
  field Link:Stream raw_stream stream
  field Link:ColorGamut gamut
  field CBool separated ; field Int page_num
  field Array stack ; field Int count <- 0
  field PDFContext context ; field List:PDFContext context_s
  field PDFText text
  field (Dictionary Str PDFObject) objects
  field Link:Dictionary xobject_dict colorspace_dict gs_dict
  field Pointer:PDFObject cobject
  field Array:Curve curves ; field Curve curve
  field Link:DrawPrototype draw
  field Str instruction
  field ExtendedStatus status <- success
  field Dictionary unknown


method pdf colorspace cs extra -> gamut
  arg_rw PDFReader pdf ; arg Address cs ; arg Str extra ; ar
  gamut :> null map ColorGamut
  if (cs is Ident)
    var Str id := cs as Ident
    if pdf:separated and (id="G" or id="DeviceGray")
  field CBool separated ; field Int page_num
  field Array stack ; field Int count <- 0
  field PDFContext context ; field List:PDFContext context_s
  field PDFText text
  field (Dictionary Str PDFObject) objects
  field Link:Dictionary xobject_dict colorspace_dict gs_dict
  field Pointer:PDFObject cobject
  field Array:Curve curves ; field Curve curve
  field Link:DrawPrototype draw
  field Str instruction
  field ExtendedStatus status <- success
  field Dictionary unknown


method pdf colorspace cs extra -> gamut
  arg_rw PDFReader pdf ; arg Address cs ; arg Str extra ; ar
  gamut :> null map ColorGamut
  if (cs is Ident)
    var Str id := cs as Ident
    if pdf:separated and (id="G" or id="DeviceGray")
      gamut :> color_gamut "pantone:"+(pdf:draw:gamut query 
      gamut :> color_gamut "pantone:"+(pdf:gamut query "component_name "+(string pdf:page_num))+extra
    eif id="G" or id="DeviceGray"
      gamut :> color_gamut "pantone:process_black"+extra
    eif id="RGB" or id="DeviceRGB"
      gamut :> color_gamut "rgb"
    eif id="DeviceCMYK"
      gamut :> color_gamut "pantone:process_cyan+process_mag
    eif (lower:id parse word:"pantone" any:(var Str pantone)
      gamut :> color_gamut "pantone:"+real_color_name:id+ext
  eif (cs is Array)
    var Pointer:Array a :> cs as Array
    if a:size>=2 and (a:0 as Ident)="DeviceN" and (a:1 is Ar
      var Pointer:Array inks :> a:1 as Array
      var Str name := ""
      for (var Int i) 0 inks:size-1
        if (entry_type inks:i)=Ident
          var Str ink := cast (inks:i map Ident) Str
          name += "+"+real_color_name:ink
      gamut :> color_gamut "pantone:"+(name 1 name:len)+extr
    eif a:size>=2 and (a:0 as Ident)="Separation"
      gamut :> color_gamut "pantone:"+real_color_name:(a:1 a
    eif a:size>0 and (a:0 as Ident)="CalRGB"
      gamut :> color_gamut "rgb"
    eif id="G" or id="DeviceGray"
      gamut :> color_gamut "pantone:process_black"+extra
    eif id="RGB" or id="DeviceRGB"
      gamut :> color_gamut "rgb"
    eif id="DeviceCMYK"
      gamut :> color_gamut "pantone:process_cyan+process_mag
    eif (lower:id parse word:"pantone" any:(var Str pantone)
      gamut :> color_gamut "pantone:"+real_color_name:id+ext
  eif (cs is Array)
    var Pointer:Array a :> cs as Array
    if a:size>=2 and (a:0 as Ident)="DeviceN" and (a:1 is Ar
      var Pointer:Array inks :> a:1 as Array
      var Str name := ""
      for (var Int i) 0 inks:size-1
        if (entry_type inks:i)=Ident
          var Str ink := cast (inks:i map Ident) Str
          name += "+"+real_color_name:ink
      gamut :> color_gamut "pantone:"+(name 1 name:len)+extr
    eif a:size>=2 and (a:0 as Ident)="Separation"
      gamut :> color_gamut "pantone:"+real_color_name:(a:1 a
    eif a:size>0 and (a:0 as Ident)="CalRGB"
      gamut :> color_gamut "rgb"
  if not exists:gamut
    console "unsupported colorspace "
    if cs<>null
      pdf display cs
    console eol
  eif gamut=failure
    console "incorrect gamut " gamut:name eol
  if exists:gamut and gamut=failure
    gamut :> null map ColorGamut


method pdf real_color gamut color -> real
  arg_rw PDFReader pdf ; oarg ColorGamut gamut ; arg ColorBu
  implicit pdf
    if separated
    gamut :> null map ColorGamut


method pdf real_color gamut color -> real
  arg_rw PDFReader pdf ; oarg ColorGamut gamut ; arg ColorBu
  implicit pdf
    if separated
      memory_copy addressof:color addressof:real draw:gamut:
      memory_copy addressof:color addressof:real pdf:gamut:pixel_size
    else
      memory_copy addressof:color addressof:(var ColorBuffer
      if context:transparency<>3
        bytes_fill (addressof:c translate Byte gamut:dimensi
    else
      memory_copy addressof:color addressof:(var ColorBuffer
      if context:transparency<>3
        bytes_fill (addressof:c translate Byte gamut:dimensi
      var Arrow speedup :=  draw:gamut speedup gamut ""
      draw:gamut convert gamut addressof:c addressof:real 1 
      var Arrow speedup :=  pdf:gamut speedup gamut ""
      pdf:gamut convert gamut addressof:c addressof:real 1 speedup
      if context:transparency<2
      if context:transparency<2
        bytes_fill (addressof:real translate Byte draw:gamut
        bytes_fill (addressof:real translate Byte pdf:gamut:dimension) 1 pdf:gamut:transparency
       


pdf_instruction cs
  var Arrow a := solve (colorspace_dict first (pick:0 as Ide
  if (pick:0 as Ident)="Pattern"
    warning "pattern painting"
    context fill_mode := 0
    context unsupported_fill := true
  eif ((a as Array):0 as Ident)="Separation" and ((a as Arra
       


pdf_instruction cs
  var Arrow a := solve (colorspace_dict first (pick:0 as Ide
  if (pick:0 as Ident)="Pattern"
    warning "pattern painting"
    context fill_mode := 0
    context unsupported_fill := true
  eif ((a as Array):0 as Ident)="Separation" and ((a as Arra
    context fill_gamut :> draw gamut
    if draw:gamut:model=color_gamut_additive
    context fill_gamut :> pdf gamut
    if pdf:gamut:model=color_gamut_additive
      context fill_gamut :> color_gamut "pantone:process_bla
    bytes_fill (addressof context:fill_color) 1 context:fill
    context fill_mode := 2
  eif { var Link:ColorGamut gamut :> colorspace a "+transpar
    context fill_gamut :> gamut
    bytes_fill (addressof context:fill_color) 1 context:fill
    context fill_mode := 1
  else
    warning "unexpected colorspace"
    context fill_mode := 0
    context unsupported_fill := true
  pop

pdf_instruction CS
  var Arrow a := solve (colorspace_dict first (pick:0 as Ide
  if (pick:0 as Ident)="Pattern"
    warning "pattern painting"
    context stroke_mode := 0
    context unsupported_stroke := true
  eif ((a as Array):0 as Ident)="Separation" and ((a as Arra
      context fill_gamut :> color_gamut "pantone:process_bla
    bytes_fill (addressof context:fill_color) 1 context:fill
    context fill_mode := 2
  eif { var Link:ColorGamut gamut :> colorspace a "+transpar
    context fill_gamut :> gamut
    bytes_fill (addressof context:fill_color) 1 context:fill
    context fill_mode := 1
  else
    warning "unexpected colorspace"
    context fill_mode := 0
    context unsupported_fill := true
  pop

pdf_instruction CS
  var Arrow a := solve (colorspace_dict first (pick:0 as Ide
  if (pick:0 as Ident)="Pattern"
    warning "pattern painting"
    context stroke_mode := 0
    context unsupported_stroke := true
  eif ((a as Array):0 as Ident)="Separation" and ((a as Arra
    context stroke_gamut :> draw gamut
    if draw:gamut:model=color_gamut_additive
    context stroke_gamut :> pdf gamut
    if pdf:gamut:model=color_gamut_additive
      context stroke_gamut :> color_gamut "pantone:process_b
    bytes_fill (addressof context:stroke_color) 1 context:st
    context stroke_mode := 2
  eif { var Link:ColorGamut gamut :> colorspace a "+transpar
    context stroke_gamut :> gamut
    bytes_fill (addressof context:stroke_color) 1 context:st
    context stroke_mode := 1
  else
    warning "unexpected colorspace"
    context stroke_mode := 0
    context unsupported_stroke := true
  pop


pdf_instruction g
  if separated
      context stroke_gamut :> color_gamut "pantone:process_b
    bytes_fill (addressof context:stroke_color) 1 context:st
    context stroke_mode := 2
  eif { var Link:ColorGamut gamut :> colorspace a "+transpar
    context stroke_gamut :> gamut
    bytes_fill (addressof context:stroke_color) 1 context:st
    context stroke_mode := 1
  else
    warning "unexpected colorspace"
    context stroke_mode := 0
    context unsupported_stroke := true
  pop


pdf_instruction g
  if separated
    memory_clear (addressof context:fill_color) draw:gamut:p
    if page_num<draw:gamut:dimension
    memory_clear (addressof context:fill_color) pdf:gamut:pixel_size
    if page_num<pdf:gamut:dimension
      context:fill_color:bytes page_num := cast 255*(bound 1
      context:fill_color:bytes page_num := cast 255*(bound 1
      context:fill_color:bytes draw:gamut:dimension+page_num
      context:fill_color:bytes pdf:gamut:dimension+page_num := 255
  else
    context fill_mode := 1
    context fill_gamut :> color_gamut "pantone:process_black
    context:fill_color:bytes 0 := cast 255*(bound 1-(pick:0 
    context:fill_color:bytes 1 := 255
  pop

pdf_instruction G
  if separated
  else
    context fill_mode := 1
    context fill_gamut :> color_gamut "pantone:process_black
    context:fill_color:bytes 0 := cast 255*(bound 1-(pick:0 
    context:fill_color:bytes 1 := 255
  pop

pdf_instruction G
  if separated
    memory_clear (addressof context:stroke_color) draw:gamut
    if page_num<draw:gamut:dimension
    memory_clear (addressof context:stroke_color) pdf:gamut:pixel_size
    if page_num<pdf:gamut:dimension
      context:stroke_color:bytes page_num := cast 255*(bound
      context:stroke_color:bytes page_num := cast 255*(bound
      context:stroke_color:bytes draw:gamut:dimension+page_n
      context:stroke_color:bytes pdf:gamut:dimension+page_num := 255
  else
    context stroke_mode := 1
    context stroke_gamut :> color_gamut "pantone:process_bla
    context:stroke_color:bytes 0 := cast 255*(bound 1-(pick:
    context:stroke_color:bytes 1 := 255
  pop



module "/pliant/graphic/vector/shading.pli"
pdf_instruction sh
  var Link:Dictionary d :> solve:(shading_dict first (pick:0
  else
    context stroke_mode := 1
    context stroke_gamut :> color_gamut "pantone:process_bla
    context:stroke_color:bytes 0 := cast 255*(bound 1-(pick:
    context:stroke_color:bytes 1 := 255
  pop



module "/pliant/graphic/vector/shading.pli"
pdf_instruction sh
  var Link:Dictionary d :> solve:(shading_dict first (pick:0
  if context:clip_x0=defined and ((d first "ShadingType") as
  var Int st := (d first "ShadingType") as Int
  if context:clip_x0=defined and (st=2 or st=3)
    var Link:ColorGamut gamut :> colorspace solve:(d first "
    if exists:gamut
      var Link:Array a :> (d first "Coords") as Array
    var Link:ColorGamut gamut :> colorspace solve:(d first "
    if exists:gamut
      var Link:Array a :> (d first "Coords") as Array
      var Point2 p0 := context:t (point (a:0 as Float) (a:1 
      var Point2 p1 := context:t (point (a:2 as Float) (a:3 
      if st=2
        var Point2 p0 := context:t (point (a:0 as Float) (a:1 as Float))
        var Point2 p1 := context:t (point (a:2 as Float) (a:3 as Float))
      eif st=3
        var Point2 p0 := context:t (point (a:0 as Float) (a:1 as Float))
        var Float r0 := norme (context:t (vector (a:2 as Float) 0))
        var Point2 p1 := context:t (point (a:3 as Float) (a:4 as Float))
        var Float r1 := norme (context:t (vector (a:5 as Float) 0))
        if (norme p1-p0)>1e-9
          warning "radial shading with different centers"
      var Link:Dictionary f :> solve:(d first "Function") as
      var ColorBuffer c0
      for (var Int i) 0 gamut:dimension-1
        c0:bytes i := cast 255*(((f first "C0") as Array):i 
      bytes_fill (addressof:c0 translate Byte gamut:dimensio
      var ColorBuffer c1
      for (var Int i) 0 gamut:dimension-1
        c1:bytes i := cast 255*(((f first "C1") as Array):i 
      bytes_fill (addressof:c1 translate Byte gamut:dimensio
      var Link:ImagePacked p :> new ImagePacked
      p setup (image_prototype context:clip_x0 context:clip_
      var Link:Dictionary f :> solve:(d first "Function") as
      var ColorBuffer c0
      for (var Int i) 0 gamut:dimension-1
        c0:bytes i := cast 255*(((f first "C0") as Array):i 
      bytes_fill (addressof:c0 translate Byte gamut:dimensio
      var ColorBuffer c1
      for (var Int i) 0 gamut:dimension-1
        c1:bytes i := cast 255*(((f first "C1") as Array):i 
      bytes_fill (addressof:c1 translate Byte gamut:dimensio
      var Link:ImagePacked p :> new ImagePacked
      p setup (image_prototype context:clip_x0 context:clip_
      p axial_shading p0 c0 p1 c1 gamut
      if st=2
        p axial_shading p0 c0 p1 c1 gamut
      eif st=3
        p radial_shading p0 r0 c0 p1 r1 c1 gamut
      draw image p transform
    else
      warning "unsupported shading colorspace"
      var Link:DrawPrototype dt :> draw trouble_open
      dt rectangle context:clip_x0 context:clip_y0 context:c
      draw trouble_close
  else
      draw image p transform
    else
      warning "unsupported shading colorspace"
      var Link:DrawPrototype dt :> draw trouble_open
      dt rectangle context:clip_x0 context:clip_y0 context:c
      draw trouble_close
  else
    warning "unsupported shading"
    warning "unsupported shading "+string:((d first "ShadingType") as Int)
    var Link:DrawPrototype dt :> draw trouble_open
    dt rectangle context:clip_x0 context:clip_y0 context:cli
    draw trouble_close
  pop


pdf_instruction Do
  function predictor a b c -> r
    arg Int a b c r
    var Int p := a+b-c
    var Int pa := abs p-a
    var Int pb := abs p-b
    var Int pc := abs p-c
    r := shunt pa<=pb and pa<=pc a pb<=pc b c
    var Link:DrawPrototype dt :> draw trouble_open
    dt rectangle context:clip_x0 context:clip_y0 context:cli
    draw trouble_close
  pop


pdf_instruction Do
  function predictor a b c -> r
    arg Int a b c r
    var Int p := a+b-c
    var Int pa := abs p-a
    var Int pb := abs p-b
    var Int pc := abs p-c
    r := shunt pa<=pb and pa<=pc a pb<=pc b c
  var Str id := pick:0 as Ident
  var Arrow a := solve (xobject_dict first (pop as Ident))
  if (a is Dictionary) and { var Link:Dictionary d :> a as D
    var Pointer:PDFObject img_object :> cobject
    if (cache_open "/pliant/pdf/image/"+img_object:cache_id 
      var CBool ok := false
  var Arrow a := solve (xobject_dict first (pop as Ident))
  if (a is Dictionary) and { var Link:Dictionary d :> a as D
    var Pointer:PDFObject img_object :> cobject
    if (cache_open "/pliant/pdf/image/"+img_object:cache_id 
      var CBool ok := false
      part load
      part load "loading image"
        var Int size_x := solve:(d first "Width") as Int
        var Int size_y := solve:(d first "Height") as Int
        var Link:ColorGamut gamut :> colorspace solve:(d fir
        if not exists:gamut
          warning "unsupported image colorspace" ; leave loa
        var CBool reverse := (solve:(d first "ColorSpace") a
        var Link:Dictionary parameters :> solve:(d first "De
        var Int predictor := solve:(parameters first "Predic
        if predictor=undefined
          predictor := 1
        var Int pred_columns := solve:(parameters first "Col
        var Int pred_bits := solve:(parameters first "BitsPe
        var Int pred_colors := solve:(parameters first "Colo
        var Int pred_step := undefined
        var Int pred_left := undefined
        if pred_columns<>undefined and pred_bits<>undefined 
          pred_step := max (pred_columns*pred_bits*pred_colo
          pred_left := max (pred_bits*pred_colors+7)\8 1
        if size_x<=0 or size_y<=0
          severe "incorrect image size" ; leave load
        var Link:ImagePacked packed :> new ImagePacked
        packed setup (image_prototype 0 0 1 1 size_x size_y 
        (raw_stream query "seek") parse (var Intn current_se
        raw_stream configure "seek "+(string img_object:seek
        var Link:Stream pixels :> filter d (var Link:ImageRe
        if not exists:pixels
        var Int size_x := solve:(d first "Width") as Int
        var Int size_y := solve:(d first "Height") as Int
        var Link:ColorGamut gamut :> colorspace solve:(d fir
        if not exists:gamut
          warning "unsupported image colorspace" ; leave loa
        var CBool reverse := (solve:(d first "ColorSpace") a
        var Link:Dictionary parameters :> solve:(d first "De
        var Int predictor := solve:(parameters first "Predic
        if predictor=undefined
          predictor := 1
        var Int pred_columns := solve:(parameters first "Col
        var Int pred_bits := solve:(parameters first "BitsPe
        var Int pred_colors := solve:(parameters first "Colo
        var Int pred_step := undefined
        var Int pred_left := undefined
        if pred_columns<>undefined and pred_bits<>undefined 
          pred_step := max (pred_columns*pred_bits*pred_colo
          pred_left := max (pred_bits*pred_colors+7)\8 1
        if size_x<=0 or size_y<=0
          severe "incorrect image size" ; leave load
        var Link:ImagePacked packed :> new ImagePacked
        packed setup (image_prototype 0 0 1 1 size_x size_y 
        (raw_stream query "seek") parse (var Intn current_se
        raw_stream configure "seek "+(string img_object:seek
        var Link:Stream pixels :> filter d (var Link:ImageRe
        if not exists:pixels
          return
          warning "unsupported image encoding" ; leave load
        if exists:decoder
          if (decoder open pixels "" (var ImagePrototype h))
            warning "failed to setup image decoder" ; leave 
        var Address buffer := (memory_zallocate packed:line_
        var Address previous := (memory_zallocate packed:lin
        var Address final := memory_zallocate packed:line_si
        var CBool passed := false
        part read_lines
          for (var Int y) 0 size_y-1
            var Int offset := 0
            while offset<packed:line_size
              var Int algo := 0 ; var Int step := packed:lin
              if predictor=1
                void
              eif predictor=15
                pixels raw_read addressof:(var uInt8 algo8) 
                if pred_step=defined
                  step := min step pred_step
              else
                algo := predictor-10
              if exists:decoder
        if exists:decoder
          if (decoder open pixels "" (var ImagePrototype h))
            warning "failed to setup image decoder" ; leave 
        var Address buffer := (memory_zallocate packed:line_
        var Address previous := (memory_zallocate packed:lin
        var Address final := memory_zallocate packed:line_si
        var CBool passed := false
        part read_lines
          for (var Int y) 0 size_y-1
            var Int offset := 0
            while offset<packed:line_size
              var Int algo := 0 ; var Int step := packed:lin
              if predictor=1
                void
              eif predictor=15
                pixels raw_read addressof:(var uInt8 algo8) 
                if pred_step=defined
                  step := min step pred_step
              else
                algo := predictor-10
              if exists:decoder
                decoder readline buffer
                if (decoder readline buffer)=failure
                  warning "failed to read image line "+(string y+1)+"/"+string:size_y ; leave read_lines
              else
                pixels raw_read buffer step
              var Address cur := buffer
              var Address stop := buffer translate Byte step
              var Int left := shunt pred_left<>undefined and
              var Int top := (cast previous Int).-.(cast buf
              var Int topleft := left+top
              if algo=0
                void
              eif algo=1
                cur := cur translate Byte -left
                while cur<>stop
                  cur map uInt8 := (cur map uInt8)+(cur map 
                  cur := cur translate uInt8 1
              eif algo=2
                while cur<>stop
                  cur map uInt8 := (cur map uInt8)+(cur map 
                  cur := cur translate uInt8 1
              eif algo=3
                while cur<>stop
                  cur map uInt8 := (cur map uInt8)+((cur map
                  cur := cur translate uInt8 1
              eif algo=4
                while cur<>stop
                  cur map uInt8 := (cur map uInt8)+(predicto
                  cur := cur translate uInt8 1
              else
                warning "Unsupported image predictor "+strin
              memory_copy buffer (final translate Byte offse
              memory_copy buffer previous step
              offset += step
            if reverse
              bytes_copy_255minus final 1 final 1 packed:lin
            packed write 0 size_y-1-y size_x final
          passed := true
        if exists:decoder
          if decoder:close=failure
            warning "failed to read image" ; leave load
        memory_free (buffer translate Byte -(packed:pixel_si
        memory_free (previous translate Byte -(packed:pixel_
        memory_free final
        packed shrink
        raw_stream configure "seek "+string:current_seek
        if pixels=failure
          warning "failed to read image" ; leave load
        (addressof:ca omap PDFImageCache) image :> packed
        ok := passed
      if ok
        cache_ready ca
      else
              else
                pixels raw_read buffer step
              var Address cur := buffer
              var Address stop := buffer translate Byte step
              var Int left := shunt pred_left<>undefined and
              var Int top := (cast previous Int).-.(cast buf
              var Int topleft := left+top
              if algo=0
                void
              eif algo=1
                cur := cur translate Byte -left
                while cur<>stop
                  cur map uInt8 := (cur map uInt8)+(cur map 
                  cur := cur translate uInt8 1
              eif algo=2
                while cur<>stop
                  cur map uInt8 := (cur map uInt8)+(cur map 
                  cur := cur translate uInt8 1
              eif algo=3
                while cur<>stop
                  cur map uInt8 := (cur map uInt8)+((cur map
                  cur := cur translate uInt8 1
              eif algo=4
                while cur<>stop
                  cur map uInt8 := (cur map uInt8)+(predicto
                  cur := cur translate uInt8 1
              else
                warning "Unsupported image predictor "+strin
              memory_copy buffer (final translate Byte offse
              memory_copy buffer previous step
              offset += step
            if reverse
              bytes_copy_255minus final 1 final 1 packed:lin
            packed write 0 size_y-1-y size_x final
          passed := true
        if exists:decoder
          if decoder:close=failure
            warning "failed to read image" ; leave load
        memory_free (buffer translate Byte -(packed:pixel_si
        memory_free (previous translate Byte -(packed:pixel_
        memory_free final
        packed shrink
        raw_stream configure "seek "+string:current_seek
        if pixels=failure
          warning "failed to read image" ; leave load
        (addressof:ca omap PDFImageCache) image :> packed
        ok := passed
      if ok
        cache_ready ca
      else
        cache_cancel ca ; return
        cache_cancel ca
        warning "failed to load image"
        return
    draw image (addressof:ca omap PDFImageCache):image conte
    draw image (addressof:ca omap PDFImageCache):image conte
  eif (a is Dictionary) and cobject:attached<>null
    check (entry_type cobject:attached)=DrawDisplayList
    (addressof:draw omap DrawDisplayList) include (cobject:attached map DrawDisplayList) context:t
  eif (a is Dictionary)
  eif (a is Dictionary)
    console "Do " ; display a false ; console eol
    # warning "unexpected Do usage"
    if (entry_type addressof:draw)=DrawDisplayList
      var Pointer:PDFObject do_object :> cobject
      var Link:DrawDisplayList memo_draw :> addressof:draw map DrawDisplayList
      var Link:DrawDisplayList sub :> new DrawDisplayList
      draw :> sub
      var Transform2 memo_t := context t
      context t := transform
    var Link:Stream current_stream :> stream
    (raw_stream query "seek") parse (var Intn current_seek)
    raw_stream configure "seek "+(string cobject:seek)
    stream :> filter (a map Dictionary) (var Link:ImageReadF
    var Link:Stream current_stream :> stream
    (raw_stream query "seek") parse (var Intn current_seek)
    raw_stream configure "seek "+(string cobject:seek)
    stream :> filter (a map Dictionary) (var Link:ImageReadF
    var Link:Dictionary colorspace_memo :> colorspace_dict
    var Link:Dictionary xobject_memo :> xobject_dict
    var Link:Dictionary gs_memo :> gs_dict
    var Link:Dictionary font_memo :> font_dict
    var Link:Dictionary shading_memo :> shading_dict
    var Link:Dictionary res :> solve:((a as Dictionary) first "Resources") map Dictionary
    if exists:res and exists:(res first "XObject")
      xobject_dict :> solve:(res first "XObject") as Dictionary
    if exists:res and exists:(res first "ColorSpace")
      colorspace_dict :> solve:(res first "ColorSpace") as Dictionary
    if exists:res and exists:(res first "ExtGState")
      gs_dict :> solve:(res first "ExtGState") as Dictionary
    if exists:res and exists:(res first "Font")
      font_dict :> solve:(res first "Font") as Dictionary
    if exists:res and exists:(res first "Shading")
      shading_dict :> solve:(res first "Shading") as Dictionary
    process_instructions
    process_instructions
    colorspace_dict :> colorspace_memo
    xobject_dict :> xobject_memo
    gs_dict :> gs_memo
    font_dict :> gs_memo
    shading_dict :> gs_memo
    raw_stream configure "seek "+string:current_seek
    stream :> current_stream
    raw_stream configure "seek "+string:current_seek
    stream :> current_stream
    if (entry_type addressof:draw)=DrawDisplayList
      context t := memo_t
      draw :> memo_draw
      memo_draw include sub context:t
      do_object attached := addressof sub
  else
    warning "unexpected Do usage"


pdf_instruction ID
  var Int isize_x := undefined ; var Int isize_y := undefine
  var Link:ColorGamut gamut :> null map ColorGamut ; var CBo
  for (var Int i) 0 count-2 step 2
    var Str id := (pick i+1) as Ident
    if id="W"
      isize_x := pick:i as Int
    eif id="H"
      isize_y := pick:i as Int
    eif id="BPC"
      bpc := pick:i as Int
      if bpc<>8
        warning "Unsupported "+string:bpc+" bits per compone
    eif id="CS"
      var Str cs := pick:i as Ident
      if separated and (cs="DeviceGray" or cs="G")


pdf_instruction ID
  var Int isize_x := undefined ; var Int isize_y := undefine
  var Link:ColorGamut gamut :> null map ColorGamut ; var CBo
  for (var Int i) 0 count-2 step 2
    var Str id := (pick i+1) as Ident
    if id="W"
      isize_x := pick:i as Int
    eif id="H"
      isize_y := pick:i as Int
    eif id="BPC"
      bpc := pick:i as Int
      if bpc<>8
        warning "Unsupported "+string:bpc+" bits per compone
    eif id="CS"
      var Str cs := pick:i as Ident
      if separated and (cs="DeviceGray" or cs="G")
        gamut :> color_gamut "pantone:"+(draw:gamut query "c
        gamut :> color_gamut "pantone:"+(pdf:gamut query "component_name "+string:page_num) ; reverse := true
      eif cs="DeviceGray" or cs="G"
        gamut :> color_gamut "pantone:process_black" ; rever
      else
        warning "unsupported inline image colorspace '"+cs+"
    else
      warning "unsupported inline image attribute '"+id+"'" 
  if not exists:gamut
    warning "unsupported inline image gamut" ; return
  if isize_x<=0 or isize_y<=0 or isize_x>2^14 or isize_y>2^1
    warning "inline image overflow" ; return
  var Link:ImagePacked packed :> new ImagePacked
  packed setup (image_prototype 0 0 1 1 isize_x isize_y gamu
  var Address buffer := memory_allocate packed:line_size nul
  for (var Int iy) 0 isize_y-1
    pdf:stream raw_read buffer packed:line_size
    if reverse
      bytes_copy_255minus buffer 1 buffer 1 packed:line_size
    packed write 0 isize_y-1-iy isize_x buffer
  memory_free buffer
  draw image packed context:t
  pop count
  if token<>"EI"
    warning "unexpected end of inline image"



pdf_instruction Tf
  text fontdef :> solve:(font_dict first (pick:1 as Ident)) 
  var Pointer:PDFObject img_object :> cobject
  if (cache_open "/pliant/graphic/pdf/font/"+img_object:cach
    var Str name := solve:(text:fontdef first "BaseFont") as
    if debug
      console "font name '" name "' " (shunt (exists text:fo
      console "font def " ; display (addressof text:fontdef)
    part compute_the_encoding
      text:encoding size := 256
      for (var Int i) 0 255
        text:encoding i := i
      var Str charset := (text:fontdef first "Encoding") as 
      if exists:(charsets first charset)
        text encoding := charsets first charset
      var Link:Dictionary enc :> solve:(text:fontdef first "
      var Str charset := (enc first "BaseEncoding") as Ident
      if exists:(charsets first charset)
        text encoding := charsets first charset
      var Link:Array diff :> solve:(enc first "Differences")
      var Int num := undefined
      for (var Int i) 0 diff:size-1
        if (diff:i is Int)
          num := diff:i as Int
        if (diff:i as Ident)<>"" and num>=0 and num<256
          var Pointer:Int unicode :> postscript_glyphs first
          if exists:unicode
            text:encoding num := unicode
          num += 1
      if solve:(text:fontdef first "ToUnicode")<>null
        var Link:Dictionary mapping :> solve:(text:fontdef f
        (raw_stream query "seek") parse (var Intn current_se
        raw_stream configure "seek "+(string cobject:seek)
        var Link:Stream s :> filter mapping (var Link:ImageR
        while not s:atend
          var Str l := s readline
          if (l parse (var Int drop) word:"beginbfchar")
            while (s:readline parse "<" any:(var Str code8) 
              var Int char := unhexa code8
              if char>=0 and char<256
                text:encoding char := unhexa code16
        raw_stream configure "seek "+string:current_seek
    text:font encoding := text encoding
    part load_the_font
      var CBool loaded := false
      var Arrow def := addressof text:fontdef
      if (text:fontdef first "DescendantFonts")<>null
        def := solve (text:fontdef first "DescendantFonts")
        if (def is Array)
          def := solve (def as Array):0
      if ((def as Dictionary) first "FontDescriptor")<>null
        def := solve ((def as Dictionary) first "FontDescrip
      for (var Int i) 0 3
        if ((def as Dictionary) first "FontFile"+(shunt i>0 
          var Link:Dictionary ff :> solve:((def as Dictionar
          if cobject:seek<>0
            (raw_stream query "seek") parse (var Intn curren
            raw_stream configure "seek "+(string cobject:see
            var Str temp := file_temporary
            var Link:Stream src :> filter ff (var Link:Image
            var Int length
            if addressof:src=(addressof pdf:raw_stream)
              length := (ff first "Length") as Int
            else
              length := 2^30
            (var Stream dest) open temp out+safe
            raw_copy src dest length length
            dest close
      eif cs="DeviceGray" or cs="G"
        gamut :> color_gamut "pantone:process_black" ; rever
      else
        warning "unsupported inline image colorspace '"+cs+"
    else
      warning "unsupported inline image attribute '"+id+"'" 
  if not exists:gamut
    warning "unsupported inline image gamut" ; return
  if isize_x<=0 or isize_y<=0 or isize_x>2^14 or isize_y>2^1
    warning "inline image overflow" ; return
  var Link:ImagePacked packed :> new ImagePacked
  packed setup (image_prototype 0 0 1 1 isize_x isize_y gamu
  var Address buffer := memory_allocate packed:line_size nul
  for (var Int iy) 0 isize_y-1
    pdf:stream raw_read buffer packed:line_size
    if reverse
      bytes_copy_255minus buffer 1 buffer 1 packed:line_size
    packed write 0 isize_y-1-iy isize_x buffer
  memory_free buffer
  draw image packed context:t
  pop count
  if token<>"EI"
    warning "unexpected end of inline image"



pdf_instruction Tf
  text fontdef :> solve:(font_dict first (pick:1 as Ident)) 
  var Pointer:PDFObject img_object :> cobject
  if (cache_open "/pliant/graphic/pdf/font/"+img_object:cach
    var Str name := solve:(text:fontdef first "BaseFont") as
    if debug
      console "font name '" name "' " (shunt (exists text:fo
      console "font def " ; display (addressof text:fontdef)
    part compute_the_encoding
      text:encoding size := 256
      for (var Int i) 0 255
        text:encoding i := i
      var Str charset := (text:fontdef first "Encoding") as 
      if exists:(charsets first charset)
        text encoding := charsets first charset
      var Link:Dictionary enc :> solve:(text:fontdef first "
      var Str charset := (enc first "BaseEncoding") as Ident
      if exists:(charsets first charset)
        text encoding := charsets first charset
      var Link:Array diff :> solve:(enc first "Differences")
      var Int num := undefined
      for (var Int i) 0 diff:size-1
        if (diff:i is Int)
          num := diff:i as Int
        if (diff:i as Ident)<>"" and num>=0 and num<256
          var Pointer:Int unicode :> postscript_glyphs first
          if exists:unicode
            text:encoding num := unicode
          num += 1
      if solve:(text:fontdef first "ToUnicode")<>null
        var Link:Dictionary mapping :> solve:(text:fontdef f
        (raw_stream query "seek") parse (var Intn current_se
        raw_stream configure "seek "+(string cobject:seek)
        var Link:Stream s :> filter mapping (var Link:ImageR
        while not s:atend
          var Str l := s readline
          if (l parse (var Int drop) word:"beginbfchar")
            while (s:readline parse "<" any:(var Str code8) 
              var Int char := unhexa code8
              if char>=0 and char<256
                text:encoding char := unhexa code16
        raw_stream configure "seek "+string:current_seek
    text:font encoding := text encoding
    part load_the_font
      var CBool loaded := false
      var Arrow def := addressof text:fontdef
      if (text:fontdef first "DescendantFonts")<>null
        def := solve (text:fontdef first "DescendantFonts")
        if (def is Array)
          def := solve (def as Array):0
      if ((def as Dictionary) first "FontDescriptor")<>null
        def := solve ((def as Dictionary) first "FontDescrip
      for (var Int i) 0 3
        if ((def as Dictionary) first "FontFile"+(shunt i>0 
          var Link:Dictionary ff :> solve:((def as Dictionar
          if cobject:seek<>0
            (raw_stream query "seek") parse (var Intn curren
            raw_stream configure "seek "+(string cobject:see
            var Str temp := file_temporary
            var Link:Stream src :> filter ff (var Link:Image
            var Int length
            if addressof:src=(addressof pdf:raw_stream)
              length := (ff first "Length") as Int
            else
              length := 2^30
            (var Stream dest) open temp out+safe
            raw_copy src dest length length
            dest close
            # file_copy temp "file:/tmp/font.bin" standard
            raw_stream configure "seek "+(string current_see
            raw_stream configure "seek "+(string current_see
            if (text:font load_freetype temp "")=success
              loaded := true
              if debug
                console "loaded FreeType font at " cobject:s
            else
              if debug
                console "failed to load FreeType font at " c
              warning "Failed to load embedded font at "+(st
            part load "loading freetype font"
              if (text:font load_postscript temp "")=success
                loaded := true
                if debug
                  console "loaded Type1 font at " cobject:seek eol
              eif (text:font load_freetype temp "")=success
                loaded := true
                if debug
                  console "loaded FreeType font at " cobject:seek eol
              else
                if debug
                  console "failed to load FreeType font at " cobject:seek eol
                warning "Failed to load embedded font at "+(string cobject:seek)
            file_delete temp
      if false # not loaded and ((def as Dictionary) first "
        var Link:Dictionary procs :> solve:((def as Dictiona
        var Int num := undefined
        for (var Int i) 0 diff:size-1
          if (diff:i is Int)
            num := diff:i as Int
          if (diff:i as Ident)<>""
            var Link:Dictionary proc :>solve:(procs first (d
            if cobject:seek<>0
              (raw_stream query "seek") parse (var Intn curr
              raw_stream configure "seek "+(string cobject:s
              var Link:Stream src :> filter proc (var Link:I
              console "glyph " (diff:i as Ident) eol
              while not src:atend
                console "  " src:readline eol
              raw_stream configure "seek "+string:current_se
      if loaded
        cache_ready ((addressof Link:Font text:font) map Lin
      else
        if debug
          console "Font '"+name+"' is missing" eol
        cache_cancel ((addressof Link:Font text:font) map Li
        text font :> null map Font
  if (exists text:font)
    text encoding := text:font encoding
  text scale := pick:0 as Float
  pop 2


pdf_instruction MP
            file_delete temp
      if false # not loaded and ((def as Dictionary) first "
        var Link:Dictionary procs :> solve:((def as Dictiona
        var Int num := undefined
        for (var Int i) 0 diff:size-1
          if (diff:i is Int)
            num := diff:i as Int
          if (diff:i as Ident)<>""
            var Link:Dictionary proc :>solve:(procs first (d
            if cobject:seek<>0
              (raw_stream query "seek") parse (var Intn curr
              raw_stream configure "seek "+(string cobject:s
              var Link:Stream src :> filter proc (var Link:I
              console "glyph " (diff:i as Ident) eol
              while not src:atend
                console "  " src:readline eol
              raw_stream configure "seek "+string:current_se
      if loaded
        cache_ready ((addressof Link:Font text:font) map Lin
      else
        if debug
          console "Font '"+name+"' is missing" eol
        cache_cancel ((addressof Link:Font text:font) map Li
        text font :> null map Font
  if (exists text:font)
    text encoding := text:font encoding
  text scale := pick:0 as Float
  pop 2


pdf_instruction MP
  console "MP " ; display pick:0 ; console eol
  if message_debug
    console "MP " ; display pick:0 ; console eol
  pop

pdf_instruction DP
  pop

pdf_instruction DP
  console "DP " ; display pick:1 ; console " " ; display pic
  if message_debug
    console "DP " ; display pick:1 ; console " " ; display pick:0 ; console eol
  pop 2

pdf_instruction BMC
  pop 2

pdf_instruction BMC
  console "BMC " ; display pick:0 ; console eol
  if message_debug
    console "BMC " ; display pick:0 ; console eol
  pop

pdf_instruction BDC
  pop

pdf_instruction BDC
  console "BDC " ; display pick:1 ; console " " ; display pi
  if message_debug
    console "BDC " ; display pick:1 ; console " " ; display pick:0 ; console eol
  pop 2

pdf_instruction EMC
  pop 2

pdf_instruction EMC
  console "EMC" eol
  if message_debug
    console "EMC" eol
  void



method pdf load base_stream options draw -> status
  oarg_rw PDFReader pdf ; arg_rw Stream base_stream ; arg St
  implicit pdf
    separated := options option "separated"
    stream :> base_stream
    raw_stream :> base_stream
    var Intn fsize := (file_query stream:name standard) size
  void



method pdf load base_stream options draw -> status
  oarg_rw PDFReader pdf ; arg_rw Stream base_stream ; arg St
  implicit pdf
    separated := options option "separated"
    stream :> base_stream
    raw_stream :> base_stream
    var Intn fsize := (file_query stream:name standard) size
    if fsize<64
      return failure:"File is too short"
    stream safe_configure "seek "+(string fsize-64)
    stream readline
    var Str l := stream readline
    while not stream :atend and { var Str next := stream  re
      l := next
    if not (l parse (var Intn offset))
      return failure:"Failed to find reference table"
    var Link:Dictionary root :> null map Dictionary
    part scan_reference
      stream configure "seek "+string:offset
      if pdf:token<>"xref"
        return failure:"Corrupted reference table (1)"
      while { var Str l := stream readline ; l<>"trailer" }
        if (l parse (var Int first) (var Int nb))
          if count<0 or nb>65536
            return failure:"Incorrect object number in refer
          for (var Int i) 0 nb-1
            var Str l := stream readline
            if (l parse (var Intn offset) (var Int version) 
              var PDFObject obj
              obj offset := offset
              obj cache_id := generate_id
              objects insert (string first+i)+" "+string:ver
            eif (l parse (var Intn offset) (var Int version)
              var PDFObject obj
              obj offset := offset
              obj cache_id := generate_id
              objects insert (string first+i)+" "+string:ver
            else
              return (failure "Unsupported reference: "+l)
        eif (l 0 1)="%"
          void
        else
          return (failure "Unsupported reference instruction
      var Str t := parse
      if t<>"startxref"
        return (failure "Unsupported trailer end: "+t)
      if not (pick:0 is Dictionary)
        return failure:"unsupported trailer content"
      var Link:Dictionary trailer :> pop as Dictionary
      if not exists:root
        root :> solve:(trailer first "Root") map Dictionary
      var Int prev := (trailer first "Prev") as Int
      if prev<>undefined
        offset := prev
        restart scan_reference
    if not (addressof:root is Dictionary)
      return failure:"failed to find root content"
    var Link:Dictionary pages :> solve:(root first "Pages") 
    if debug
      console "pages " ; display addressof:pages ; console e
    pdf scan_pages_list addressof:pages (var Array pages_arr
    pdf draw :> draw
    for (var Int page_num) (options option "page" Int 1)-1 (
      pdf page_num := page_num
      context fill_mode := 0
      context stroke_mode := 0
      context transparency := 0
      context line_width := 0
      text font :> null map Font
      text fontdef :> new Dictionary
      text scale := 1
      text tlm := transform 0 0 1 1 0 0
      text tm := text tlm
    stream safe_configure "seek "+(string fsize-64)
    stream readline
    var Str l := stream readline
    while not stream :atend and { var Str next := stream  re
      l := next
    if not (l parse (var Intn offset))
      return failure:"Failed to find reference table"
    var Link:Dictionary root :> null map Dictionary
    part scan_reference
      stream configure "seek "+string:offset
      if pdf:token<>"xref"
        return failure:"Corrupted reference table (1)"
      while { var Str l := stream readline ; l<>"trailer" }
        if (l parse (var Int first) (var Int nb))
          if count<0 or nb>65536
            return failure:"Incorrect object number in refer
          for (var Int i) 0 nb-1
            var Str l := stream readline
            if (l parse (var Intn offset) (var Int version) 
              var PDFObject obj
              obj offset := offset
              obj cache_id := generate_id
              objects insert (string first+i)+" "+string:ver
            eif (l parse (var Intn offset) (var Int version)
              var PDFObject obj
              obj offset := offset
              obj cache_id := generate_id
              objects insert (string first+i)+" "+string:ver
            else
              return (failure "Unsupported reference: "+l)
        eif (l 0 1)="%"
          void
        else
          return (failure "Unsupported reference instruction
      var Str t := parse
      if t<>"startxref"
        return (failure "Unsupported trailer end: "+t)
      if not (pick:0 is Dictionary)
        return failure:"unsupported trailer content"
      var Link:Dictionary trailer :> pop as Dictionary
      if not exists:root
        root :> solve:(trailer first "Root") map Dictionary
      var Int prev := (trailer first "Prev") as Int
      if prev<>undefined
        offset := prev
        restart scan_reference
    if not (addressof:root is Dictionary)
      return failure:"failed to find root content"
    var Link:Dictionary pages :> solve:(root first "Pages") 
    if debug
      console "pages " ; display addressof:pages ; console e
    pdf scan_pages_list addressof:pages (var Array pages_arr
    pdf draw :> draw
    for (var Int page_num) (options option "page" Int 1)-1 (
      pdf page_num := page_num
      context fill_mode := 0
      context stroke_mode := 0
      context transparency := 0
      context line_width := 0
      text font :> null map Font
      text fontdef :> new Dictionary
      text scale := 1
      text tlm := transform 0 0 1 1 0 0
      text tm := text tlm
      if separated
      if false # FIXME separated
        memory_clear (addressof context:fill_color) draw:gam
        if page_num<draw:gamut:dimension
          context fill_mode := 1
          context:fill_color:bytes page_num := 255
          context:fill_color:bytes draw:gamut:dimension+page
          context stroke_mode := 1
          context:stroke_color:bytes page_num := 255
          context:stroke_color:bytes draw:gamut:dimension+pa
      else
        context fill_gamut :> color_gamut "pantone:process_b
        context:fill_color:bytes 0 := 255
        context:fill_color:bytes 1 := 255
      if page_num<0 or page_num>=pages_array:size
        return (failure "no page "+(string page_num+1))
      var Link:Dictionary page :> (pdf solve pages_array:pag
      if debug
        console "page " ; display addressof:page ; console e
      context t := transform 0 0 25.4/72 25.4/72 0 0
      var Link:Array box :> solve:(page first "CropBox") as 
      if box:size<4
        box :> solve:(page first "MediaBox") as Array
      var Float bx0 := box:0 as Float
      var Float by0 := box:1 as Float
      var Float bx1 := box:2 as Float
      var Float by1 := box:3 as Float
      if bx0=undefined or by0=undefined or bx1=undefined or 
        memory_clear (addressof context:fill_color) draw:gam
        if page_num<draw:gamut:dimension
          context fill_mode := 1
          context:fill_color:bytes page_num := 255
          context:fill_color:bytes draw:gamut:dimension+page
          context stroke_mode := 1
          context:stroke_color:bytes page_num := 255
          context:stroke_color:bytes draw:gamut:dimension+pa
      else
        context fill_gamut :> color_gamut "pantone:process_b
        context:fill_color:bytes 0 := 255
        context:fill_color:bytes 1 := 255
      if page_num<0 or page_num>=pages_array:size
        return (failure "no page "+(string page_num+1))
      var Link:Dictionary page :> (pdf solve pages_array:pag
      if debug
        console "page " ; display addressof:page ; console e
      context t := transform 0 0 25.4/72 25.4/72 0 0
      var Link:Array box :> solve:(page first "CropBox") as 
      if box:size<4
        box :> solve:(page first "MediaBox") as Array
      var Float bx0 := box:0 as Float
      var Float by0 := box:1 as Float
      var Float bx1 := box:2 as Float
      var Float by1 := box:3 as Float
      if bx0=undefined or by0=undefined or bx1=undefined or 
        # return failure:"failed to get page dimensions"
        bx0 := 0 ; by0 := 0 ; bx1 := 210*72/25.4 ; by1 := 29
        bx0 := 0 ; by0 := 0 ; bx1 := 210*72/25.4 ; by1 := 29
      if bx1<=bx0 or by1<=by0
        return (failure "Incorrect page format "+(string (bx1-bx0)/72*25.4)+" x "+(string (by1-by0)/72*25.4))
      context t := compose (transform -bx0 -by1 1 1 0 0) (tr
      pdf xobject_dict :> new Dictionary
      pdf colorspace_dict :> new Dictionary
      pdf gs_dict :> new Dictionary
      pdf shading_dict :> new Dictionary
      var Link:Dictionary res :> solve:(page first "Resource
      if not exists:res
        res :>  solve:(pages first "Resources") as Dictionar
      # console "ressources " ; display addressof:res ; cons
      pdf xobject_dict :> solve:(res first "XObject") as Dic
      pdf colorspace_dict :> solve:(res first "ColorSpace") 
      context t := compose (transform -bx0 -by1 1 1 0 0) (tr
      pdf xobject_dict :> new Dictionary
      pdf colorspace_dict :> new Dictionary
      pdf gs_dict :> new Dictionary
      pdf shading_dict :> new Dictionary
      var Link:Dictionary res :> solve:(page first "Resource
      if not exists:res
        res :>  solve:(pages first "Resources") as Dictionar
      # console "ressources " ; display addressof:res ; cons
      pdf xobject_dict :> solve:(res first "XObject") as Dic
      pdf colorspace_dict :> solve:(res first "ColorSpace") 
      # console "colorspaces are " ; display addressof:colorspace_dict true ; console eol
      var Str gamutname := options option "gamut" Str
      if gamutname=""
        var Int maxi := 4
        each colorspace colorspace_dict
          var Link:Array a :> solve:colorspace as Array
          # console "  " ; display addressof:a ; console eol
          if a:size>=2 and (a:0 as Ident)="DeviceN"
            maxi := max maxi (a:1 as Array):size
        var Str gamutname := "+" ; var CBool some := false
        for (var Int count) maxi 1 step -1
          each colorspace colorspace_dict
            var Link:Array a :> solve:colorspace as Array
            if a:size>=2 and (a:0 as Ident)="Separation" and
              var Str ink := real_color_name (a:1 as Ident)
              if (gamutname search "+"+ink+"+" -1)=(-1) and 
                gamutname += ink+"+" ; some := true
            eif a:size>=2 and (a:0 as Ident)="DeviceN" and (
              var Link:Array inks :> a:1 as Array
              for (var Int i) 0 inks:size-1
                var Str ink := real_color_name (inks:i as Id
                if (gamutname search "+"+ink+"+" -1)=(-1)
                  gamutname += ink+"+" ; some := true
            eif (solve:colorspace as Ident)="DeviceCMYK" and
              for (var Int i) 0 3
                var Str ink := "process_"+(shunt i=0 "cyan" 
                if (gamutname search "+"+ink+"+" -1)=(-1)
                  gamutname += ink+"+" ; some := true
        if some
          gamutname := "pantone:"+(gamutname 1 gamutname:len
        else
          gamutname := "rgb"
      var Str gamutname := options option "gamut" Str
      if gamutname=""
        var Int maxi := 4
        each colorspace colorspace_dict
          var Link:Array a :> solve:colorspace as Array
          # console "  " ; display addressof:a ; console eol
          if a:size>=2 and (a:0 as Ident)="DeviceN"
            maxi := max maxi (a:1 as Array):size
        var Str gamutname := "+" ; var CBool some := false
        for (var Int count) maxi 1 step -1
          each colorspace colorspace_dict
            var Link:Array a :> solve:colorspace as Array
            if a:size>=2 and (a:0 as Ident)="Separation" and
              var Str ink := real_color_name (a:1 as Ident)
              if (gamutname search "+"+ink+"+" -1)=(-1) and 
                gamutname += ink+"+" ; some := true
            eif a:size>=2 and (a:0 as Ident)="DeviceN" and (
              var Link:Array inks :> a:1 as Array
              for (var Int i) 0 inks:size-1
                var Str ink := real_color_name (inks:i as Id
                if (gamutname search "+"+ink+"+" -1)=(-1)
                  gamutname += ink+"+" ; some := true
            eif (solve:colorspace as Ident)="DeviceCMYK" and
              for (var Int i) 0 3
                var Str ink := "process_"+(shunt i=0 "cyan" 
                if (gamutname search "+"+ink+"+" -1)=(-1)
                  gamutname += ink+"+" ; some := true
        if some
          gamutname := "pantone:"+(gamutname 1 gamutname:len
        else
          gamutname := "rgb"
      var Float margin := options option "margin" Float 0
      draw smart_setup (image_prototype -margin -margin (bx1
      pdf gamut :> color_gamut gamutname
      if pdf:gamut=failure
        return (failure "Incorrect gamut '"+gamutname+"' ("+pdf:gamut:message+")")
      draw setup (image_prototype 0 0 (bx1-bx0)/72*25.4 (by1-by0)/72*25.4 undefined undefined pdf:gamut) options+" page_count "+(string pages_array:size)
      pdf gs_dict :> solve:(res first "ExtGState") as Dictio
      pdf font_dict :> solve:(res first "Font") as Dictionar
      pdf shading_dict :> solve:(res first "Shading") as Dic
      var Link:Array contents
      var Address c := solve:(page first "Contents")
      if (c is Array)
        contents :> c as Array
      eif (c is Dictionary)
        contents :> new Array
        contents size := 1
        contents 0 := c
      else
        return failure:"no page content"
      for (var Int i) 0 contents:size-1
        var Link:Dictionary content :> (solve contents:i) ma
        if not (addressof:content is Dictionary)
          return failure:"no page content"
        stream configure "seek "+(string cobject:seek)
        stream :> filter content (var Link:ImageReadFilter d
        process_instructions
        stream :> raw_stream
        if pdf:status=failure
          return pdf:status
      if pdf:count>0
        warning (string pdf:count)+" dust objects on the sta
        pop count
    status := success

draw_record_filters ".pdf" PDFReader Void
      pdf gs_dict :> solve:(res first "ExtGState") as Dictio
      pdf font_dict :> solve:(res first "Font") as Dictionar
      pdf shading_dict :> solve:(res first "Shading") as Dic
      var Link:Array contents
      var Address c := solve:(page first "Contents")
      if (c is Array)
        contents :> c as Array
      eif (c is Dictionary)
        contents :> new Array
        contents size := 1
        contents 0 := c
      else
        return failure:"no page content"
      for (var Int i) 0 contents:size-1
        var Link:Dictionary content :> (solve contents:i) ma
        if not (addressof:content is Dictionary)
          return failure:"no page content"
        stream configure "seek "+(string cobject:seek)
        stream :> filter content (var Link:ImageReadFilter d
        process_instructions
        stream :> raw_stream
        if pdf:status=failure
          return pdf:status
      if pdf:count>0
        warning (string pdf:count)+" dust objects on the sta
        pop count
    status := success

draw_record_filters ".pdf" PDFReader Void