Patch title: Release 85 bulk changes
Abstract:
File: /pliant/graphic/image/sharpening.pli
Key:
    Removed line
    Added line
module "/pliant/language/compiler.pli"
submodule "prototype.pli"
module "/pliant/language/compiler/type/inherit.pli"
module "/pliant/graphic/color/gamut.pli"
module "/pliant/graphic/misc/int.pli"

# FIXME: Sharpening is not burst compatible

type ImageSharpening
  inherit ImagePrototype
  field Link:ImagePrototype image
  field Address buffer ; field Int y
  field Float intensity
  field ColorBuffer ground
  field Array:Float32 remain
  field uInt random_bits ; field Int random_available

ImagePrototype maybe ImageSharpening


function build s
  arg_w ImageSharpening s
  s buffer := null

function destroy s
  arg_w ImageSharpening s
  memory_free s:buffer


method s bind image intensity -> status
  arg_rw ImageSharpening s ; oarg ImagePrototype image ; arg Float intensity ; arg ExtendedStatus status
  memory_free s:buffer
  addressof:s map ImagePrototype := addressof:image map ImagePrototype
  s image :> image
  s buffer := memory_allocate 3*(s:line_size+2*s:pixel_size) addressof:s
  s y := undefined
  s intensity := intensity/20
  s:remain  size := s:line_size+s:gamut:pixel_size
  for (var Int i) 0 s:remain:size-1
    s:remain i := 0
  s random_available := 0
  for (var Int i) 0 s:gamut:pixel_size-1
    s:ground:bytes i := shunt s:gamut:model=color_gamut_additive 255 0
  status := success

method s setup image options -> status
  arg_rw ImageSharpening s ; arg ImagePrototype image ; arg Str options ; arg ExtendedStatus status
  var Float intensity := options option "intensity" Float
  if intensity=undefined
    return failure:"Sharpening intensity is not defined"
  status := s bind (addressof:image omap ImagePrototype) intensity


method s read_line y buffer
  oarg_rw ImageSharpening s ; arg Int y ; arg Address buffer
  if y>=0 and y<s:size_y
    memory_clear buffer s:pixel_size
    memory_copy (addressof s:ground) buffer s:pixel_size
    s:image read 0 y s:size_x (buffer translate Byte s:pixel_size)
    memory_clear (buffer translate Byte s:pixel_size+s:line_size) s:pixel_size
    memory_copy (addressof s:ground) (buffer translate Byte s:pixel_size+s:line_size) s:pixel_size
  else
    memory_clear buffer s:line_size+2*s:pixel_size
    for (var Int x) 0 s:size_x+1
      memory_copy (addressof s:ground) (buffer translate Byte x*s:pixel_size) s:pixel_size

function min a b c -> m
  arg Int a b c m
  m := min (min a b) c

function max a b c -> m
  arg Int a b c m
  m := max (max a b) c

method s read x y count adr
  oarg_rw ImageSharpening s ; arg Int x y count ; arg Address adr
  if y=s:y
    void
  eif y=s:y+1
    memory_move (s:buffer translate Byte s:line_size+2*s:pixel_size) s:buffer 2*(s:line_size+2*s:pixel_size)
    s read_line y+1 (s:buffer translate Byte 2*(s:line_size+2*s:pixel_size))
  else
    for (var Int i) 0 2
      s read_line y+i-1 (s:buffer translate Byte i*(s:line_size+2*s:pixel_size))
  s y := y
  var Address src := s:buffer translate Byte s:line_size+(3+x)*s:pixel_size
  var Int step_x := s:pixel_size
  var Int step_y := s:line_size+2*s:pixel_size
  var Address stop := src translate uInt8 count*s:gamut:pixel_size
  var Address dest := adr
  var Pointer:Float32 remain :> s:remain x*s:gamut:pixel_size
  var Int remain_step := s:gamut:pixel_size*Float32:size
  var uInt bits := s random_bits ; var Int available := s random_available
  var Float intensity := s intensity
  while src<>stop
    var Int v
    var Int v ; var Float f
    v := -2*(src map uInt8 -step_x-step_y) + -3*(src map uInt8 -step_y) + -2*(src map uInt8 step_x-step_y)
    v += -3*(src map uInt8 -step_x) + 20*(src map uInt8 0) + -3*(src map uInt8 step_x)
    v += -2*(src map uInt8 -step_x+step_y) + -3*(src map uInt8 step_y) + -2*(src map uInt8 step_x+step_y)
    var Float f := remain+(src map uInt8)+v*s:intensity
    v := bound (cast f Int) 0 255
    f := (src map uInt8)+v*intensity
    v := bound (cast remain+f Int) 0 255
    dest map uInt8 := v
    f -= v
    if available=0
      memory_random addressof:bits uInt:size
      available := uInt:size*8
    if (bits .and. 1)<>0 # send to the right
      remain := 0
      (addressof:remain translate Byte remain_step) map Float32 := f
    else # send to the bottom
      remain := f
    bits := bits\2 ; available -= 1
    src := src translate uInt8 1
    dest := dest translate uInt8 1
    remain :> (addressof:remain translate Float32 1) map Float32
  s random_bits := bits
  s random_available := available


export ImageSharpening '. bind'