aboutsummaryrefslogtreecommitdiff
path: root/sys/plio/tf
diff options
context:
space:
mode:
authorJoe Hunkeler <jhunkeler@gmail.com>2015-08-11 16:51:37 -0400
committerJoe Hunkeler <jhunkeler@gmail.com>2015-08-11 16:51:37 -0400
commit40e5a5811c6ffce9b0974e93cdd927cbcf60c157 (patch)
tree4464880c571602d54f6ae114729bf62a89518057 /sys/plio/tf
downloadiraf-osx-40e5a5811c6ffce9b0974e93cdd927cbcf60c157.tar.gz
Repatch (from linux) of OSX IRAF
Diffstat (limited to 'sys/plio/tf')
-rw-r--r--sys/plio/tf/mkpkg51
-rw-r--r--sys/plio/tf/plglpi.x38
-rw-r--r--sys/plio/tf/plglpl.x38
-rw-r--r--sys/plio/tf/plglps.x38
-rw-r--r--sys/plio/tf/plglri.x44
-rw-r--r--sys/plio/tf/plglrl.x44
-rw-r--r--sys/plio/tf/plglrs.x44
-rw-r--r--sys/plio/tf/pll2pi.x105
-rw-r--r--sys/plio/tf/pll2pl.x105
-rw-r--r--sys/plio/tf/pll2ps.x105
-rw-r--r--sys/plio/tf/pll2ri.x117
-rw-r--r--sys/plio/tf/pll2rl.x117
-rw-r--r--sys/plio/tf/pll2rs.x117
-rw-r--r--sys/plio/tf/plp2li.x126
-rw-r--r--sys/plio/tf/plp2ll.x126
-rw-r--r--sys/plio/tf/plp2ls.x126
-rw-r--r--sys/plio/tf/plp2ri.x71
-rw-r--r--sys/plio/tf/plp2rl.x71
-rw-r--r--sys/plio/tf/plp2rs.x71
-rw-r--r--sys/plio/tf/plplpi.x41
-rw-r--r--sys/plio/tf/plplpl.x41
-rw-r--r--sys/plio/tf/plplps.x41
-rw-r--r--sys/plio/tf/plplri.x41
-rw-r--r--sys/plio/tf/plplrl.x41
-rw-r--r--sys/plio/tf/plplrs.x41
-rw-r--r--sys/plio/tf/plpropi.x177
-rw-r--r--sys/plio/tf/plpropl.x177
-rw-r--r--sys/plio/tf/plprops.x177
-rw-r--r--sys/plio/tf/plr2li.x130
-rw-r--r--sys/plio/tf/plr2ll.x130
-rw-r--r--sys/plio/tf/plr2ls.x130
-rw-r--r--sys/plio/tf/plr2pi.x74
-rw-r--r--sys/plio/tf/plr2pl.x74
-rw-r--r--sys/plio/tf/plr2ps.x74
-rw-r--r--sys/plio/tf/plreqi.x27
-rw-r--r--sys/plio/tf/plreql.x27
-rw-r--r--sys/plio/tf/plreqs.x27
-rw-r--r--sys/plio/tf/plrpri.x56
-rw-r--r--sys/plio/tf/plrprl.x56
-rw-r--r--sys/plio/tf/plrprs.x56
-rw-r--r--sys/plio/tf/plrropi.x195
-rw-r--r--sys/plio/tf/plrropl.x195
-rw-r--r--sys/plio/tf/plrrops.x195
43 files changed, 3777 insertions, 0 deletions
diff --git a/sys/plio/tf/mkpkg b/sys/plio/tf/mkpkg
new file mode 100644
index 00000000..00a4d40e
--- /dev/null
+++ b/sys/plio/tf/mkpkg
@@ -0,0 +1,51 @@
+# Update the type expanded generic files in the PLIO package library.
+
+$checkout libex.a lib$
+$update libex.a
+$checkin libex.a lib$
+$exit
+
+libex.a:
+ plglpi.x <plio.h>
+ plglpl.x <plio.h>
+ plglps.x <plio.h>
+ plglri.x <plio.h> <plset.h>
+ plglrl.x <plio.h> <plset.h>
+ plglrs.x <plio.h> <plset.h>
+ pll2pi.x <plio.h>
+ pll2pl.x <plio.h>
+ pll2ps.x <plio.h>
+ pll2ri.x <plio.h> <plset.h>
+ pll2rl.x <plio.h> <plset.h>
+ pll2rs.x <plio.h> <plset.h>
+ plp2li.x <plio.h>
+ plp2ll.x <plio.h>
+ plp2ls.x <plio.h>
+ plp2ri.x <plio.h> <plset.h>
+ plp2rl.x <plio.h> <plset.h>
+ plp2rs.x <plio.h> <plset.h>
+ plplpi.x <plio.h>
+ plplpl.x <plio.h>
+ plplps.x <plio.h>
+ plplri.x <plio.h>
+ plplrl.x <plio.h>
+ plplrs.x <plio.h>
+ plpropi.x <plio.h> <plset.h>
+ plpropl.x <plio.h> <plset.h>
+ plprops.x <plio.h> <plset.h>
+ plr2li.x <plio.h> <plset.h>
+ plr2ll.x <plio.h> <plset.h>
+ plr2ls.x <plio.h> <plset.h>
+ plr2pi.x <plio.h> <plset.h>
+ plr2pl.x <plio.h> <plset.h>
+ plr2ps.x <plio.h> <plset.h>
+ plreqi.x <plset.h>
+ plreql.x <plset.h>
+ plreqs.x <plset.h>
+ plrpri.x <plio.h> <plset.h>
+ plrprl.x <plio.h> <plset.h>
+ plrprs.x <plio.h> <plset.h>
+ plrropi.x <plio.h> <plset.h> ../plrseg.h
+ plrropl.x <plio.h> <plset.h> ../plrseg.h
+ plrrops.x <plio.h> <plset.h> ../plrseg.h
+ ;
diff --git a/sys/plio/tf/plglpi.x b/sys/plio/tf/plglpi.x
new file mode 100644
index 00000000..3724ed6d
--- /dev/null
+++ b/sys/plio/tf/plglpi.x
@@ -0,0 +1,38 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plio.h>
+
+# PL_GLP -- Get a line segment as a pixel array, applying the given ROP to
+# combine the pixels with those of the output array.
+
+procedure pl_glpi (pl, v, px_dst, px_depth, npix, rop)
+
+pointer pl #I mask descriptor
+long v[PL_MAXDIM] #I vector coords of line segment
+int px_dst[ARB] #O output pixel array
+int px_depth #I pixel depth, bits
+int npix #I number of pixels desired
+int rop #I rasterop
+
+int np
+pointer sp, px_out, ll_src
+pointer pl_access()
+int pl_l2pi()
+errchk pl_access
+
+begin
+ ll_src = pl_access (pl,v)
+ if (!R_NEED_DST(rop)) {
+ np = pl_l2pi (Mems[ll_src], v[1], px_dst, npix)
+ return
+ }
+
+ call smark (sp)
+ call salloc (px_out, npix, TY_INT)
+
+ np = pl_l2pi (Mems[ll_src], v[1], Memi[px_out], npix)
+ call pl_pixropi (Memi[px_out], 1, PL_MAXVAL(pl),
+ px_dst, 1, MV(px_depth), npix, rop)
+
+ call sfree (sp)
+end
diff --git a/sys/plio/tf/plglpl.x b/sys/plio/tf/plglpl.x
new file mode 100644
index 00000000..6e1632c0
--- /dev/null
+++ b/sys/plio/tf/plglpl.x
@@ -0,0 +1,38 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plio.h>
+
+# PL_GLP -- Get a line segment as a pixel array, applying the given ROP to
+# combine the pixels with those of the output array.
+
+procedure pl_glpl (pl, v, px_dst, px_depth, npix, rop)
+
+pointer pl #I mask descriptor
+long v[PL_MAXDIM] #I vector coords of line segment
+long px_dst[ARB] #O output pixel array
+int px_depth #I pixel depth, bits
+int npix #I number of pixels desired
+int rop #I rasterop
+
+int np
+pointer sp, px_out, ll_src
+pointer pl_access()
+int pl_l2pl()
+errchk pl_access
+
+begin
+ ll_src = pl_access (pl,v)
+ if (!R_NEED_DST(rop)) {
+ np = pl_l2pl (Mems[ll_src], v[1], px_dst, npix)
+ return
+ }
+
+ call smark (sp)
+ call salloc (px_out, npix, TY_LONG)
+
+ np = pl_l2pl (Mems[ll_src], v[1], Meml[px_out], npix)
+ call pl_pixropl (Meml[px_out], 1, PL_MAXVAL(pl),
+ px_dst, 1, MV(px_depth), npix, rop)
+
+ call sfree (sp)
+end
diff --git a/sys/plio/tf/plglps.x b/sys/plio/tf/plglps.x
new file mode 100644
index 00000000..728beb0a
--- /dev/null
+++ b/sys/plio/tf/plglps.x
@@ -0,0 +1,38 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plio.h>
+
+# PL_GLP -- Get a line segment as a pixel array, applying the given ROP to
+# combine the pixels with those of the output array.
+
+procedure pl_glps (pl, v, px_dst, px_depth, npix, rop)
+
+pointer pl #I mask descriptor
+long v[PL_MAXDIM] #I vector coords of line segment
+short px_dst[ARB] #O output pixel array
+int px_depth #I pixel depth, bits
+int npix #I number of pixels desired
+int rop #I rasterop
+
+int np
+pointer sp, px_out, ll_src
+pointer pl_access()
+int pl_l2ps()
+errchk pl_access
+
+begin
+ ll_src = pl_access (pl,v)
+ if (!R_NEED_DST(rop)) {
+ np = pl_l2ps (Mems[ll_src], v[1], px_dst, npix)
+ return
+ }
+
+ call smark (sp)
+ call salloc (px_out, npix, TY_SHORT)
+
+ np = pl_l2ps (Mems[ll_src], v[1], Mems[px_out], npix)
+ call pl_pixrops (Mems[px_out], 1, PL_MAXVAL(pl),
+ px_dst, 1, MV(px_depth), npix, rop)
+
+ call sfree (sp)
+end
diff --git a/sys/plio/tf/plglri.x b/sys/plio/tf/plglri.x
new file mode 100644
index 00000000..3f031ee5
--- /dev/null
+++ b/sys/plio/tf/plglri.x
@@ -0,0 +1,44 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plio.h>
+include <plset.h>
+
+# PL_GLR -- Get a line segment as a range list, applying the given ROP to
+# combine the pixels with those of the output list.
+
+procedure pl_glri (pl, v, rl_dst, rl_depth, npix, rop)
+
+pointer pl #I mask descriptor
+long v[PL_MAXDIM] #I vector coords of line segment
+int rl_dst[ARB] #O output range list
+int rl_depth #I range list depth, bits
+int npix #I number of pixels desired
+int rop #I rasterop
+
+int mr, nr
+pointer sp, rl_out, rl_src, ll_src
+pointer pl_access()
+int pl_l2ri()
+errchk pl_access
+
+begin
+ ll_src = pl_access (pl,v)
+ if (!R_NEED_DST(rop))
+ nr = pl_l2ri (Mems[ll_src], v[1], rl_dst, npix)
+ else {
+ call smark (sp)
+ mr = min (RL_MAXLEN(pl), npix * 3)
+ call salloc (rl_src, mr, TY_INT)
+ call salloc (rl_out, mr, TY_INT)
+
+ nr = pl_l2ri (Mems[ll_src], v[1], Memi[rl_src], npix)
+ call pl_rangeropi (Memi[rl_src], 1, PL_MAXVAL(pl),
+ rl_dst, 1, MV(rl_depth),
+ Memi[rl_out], npix, rop)
+
+ # Copy out the edited range list.
+ call amovi (Memi[rl_out], rl_dst, RLI_LEN(rl_out))
+
+ call sfree (sp)
+ }
+end
diff --git a/sys/plio/tf/plglrl.x b/sys/plio/tf/plglrl.x
new file mode 100644
index 00000000..cf30dc62
--- /dev/null
+++ b/sys/plio/tf/plglrl.x
@@ -0,0 +1,44 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plio.h>
+include <plset.h>
+
+# PL_GLR -- Get a line segment as a range list, applying the given ROP to
+# combine the pixels with those of the output list.
+
+procedure pl_glrl (pl, v, rl_dst, rl_depth, npix, rop)
+
+pointer pl #I mask descriptor
+long v[PL_MAXDIM] #I vector coords of line segment
+long rl_dst[ARB] #O output range list
+int rl_depth #I range list depth, bits
+int npix #I number of pixels desired
+int rop #I rasterop
+
+int mr, nr
+pointer sp, rl_out, rl_src, ll_src
+pointer pl_access()
+int pl_l2rl()
+errchk pl_access
+
+begin
+ ll_src = pl_access (pl,v)
+ if (!R_NEED_DST(rop))
+ nr = pl_l2rl (Mems[ll_src], v[1], rl_dst, npix)
+ else {
+ call smark (sp)
+ mr = min (RL_MAXLEN(pl), npix * 3)
+ call salloc (rl_src, mr, TY_LONG)
+ call salloc (rl_out, mr, TY_LONG)
+
+ nr = pl_l2rl (Mems[ll_src], v[1], Meml[rl_src], npix)
+ call pl_rangeropl (Meml[rl_src], 1, PL_MAXVAL(pl),
+ rl_dst, 1, MV(rl_depth),
+ Meml[rl_out], npix, rop)
+
+ # Copy out the edited range list.
+ call amovl (Meml[rl_out], rl_dst, RLL_LEN(rl_out))
+
+ call sfree (sp)
+ }
+end
diff --git a/sys/plio/tf/plglrs.x b/sys/plio/tf/plglrs.x
new file mode 100644
index 00000000..4c9c90a4
--- /dev/null
+++ b/sys/plio/tf/plglrs.x
@@ -0,0 +1,44 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plio.h>
+include <plset.h>
+
+# PL_GLR -- Get a line segment as a range list, applying the given ROP to
+# combine the pixels with those of the output list.
+
+procedure pl_glrs (pl, v, rl_dst, rl_depth, npix, rop)
+
+pointer pl #I mask descriptor
+long v[PL_MAXDIM] #I vector coords of line segment
+short rl_dst[ARB] #O output range list
+int rl_depth #I range list depth, bits
+int npix #I number of pixels desired
+int rop #I rasterop
+
+int mr, nr
+pointer sp, rl_out, rl_src, ll_src
+pointer pl_access()
+int pl_l2rs()
+errchk pl_access
+
+begin
+ ll_src = pl_access (pl,v)
+ if (!R_NEED_DST(rop))
+ nr = pl_l2rs (Mems[ll_src], v[1], rl_dst, npix)
+ else {
+ call smark (sp)
+ mr = min (RL_MAXLEN(pl), npix * 3)
+ call salloc (rl_src, mr, TY_SHORT)
+ call salloc (rl_out, mr, TY_SHORT)
+
+ nr = pl_l2rs (Mems[ll_src], v[1], Mems[rl_src], npix)
+ call pl_rangerops (Mems[rl_src], 1, PL_MAXVAL(pl),
+ rl_dst, 1, MV(rl_depth),
+ Mems[rl_out], npix, rop)
+
+ # Copy out the edited range list.
+ call amovs (Mems[rl_out], rl_dst, RLS_LEN(rl_out))
+
+ call sfree (sp)
+ }
+end
diff --git a/sys/plio/tf/pll2pi.x b/sys/plio/tf/pll2pi.x
new file mode 100644
index 00000000..cadea930
--- /dev/null
+++ b/sys/plio/tf/pll2pi.x
@@ -0,0 +1,105 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plio.h>
+
+# PL_L2P -- Convert a line list to a pixel array. The number of pixels output
+# (always npix) is returned as the function value.
+
+int procedure pl_l2pi (ll_src, xs, px_dst, npix)
+
+short ll_src[ARB] #I input line list
+int xs #I starting index in ll_src
+int px_dst[ARB] #O output pixel array
+int npix #I number of pixels to convert
+
+int pv
+bool skipword
+int opcode, data, ll_len, ll_first
+int x1, x2, i1, i2, xe, np, ip, op, otop, i
+define putpix_ 91
+
+begin
+ # Support old format line lists.
+ if (LL_OLDFORMAT(ll_src)) {
+ ll_len = OLL_LEN(ll_src)
+ ll_first = OLL_FIRST
+ } else {
+ ll_len = LL_LEN(ll_src)
+ ll_first = LL_FIRST(ll_src)
+ }
+
+ # No pixels?
+ if (npix <= 0 || ll_len <= 0)
+ return (0)
+
+ xe = xs + npix - 1
+ skipword = false
+ op = 1
+ x1 = 1
+ pv = 1
+
+ do ip = ll_first, ll_len {
+ if (skipword) {
+ skipword = false
+ next
+ }
+
+ opcode = I_OPCODE(ll_src[ip])
+ data = I_DATA(ll_src[ip])
+
+ switch (opcode) {
+ case I_ZN, I_HN, I_PN:
+ # Determine inbounds region of segment.
+ x2 = x1 + data - 1
+ i1 = max (x1, xs)
+ i2 = min (x2, xe)
+
+ # Process segment if any region is inbounds.
+ np = i2 - i1 + 1
+ if (np > 0) {
+ otop = op + np - 1
+ if (opcode == I_HN) {
+ do i = op, otop
+ px_dst[i] = pv
+ } else {
+ do i = op, otop
+ px_dst[i] = 0
+ if (opcode == I_PN && i2 == x2)
+ px_dst[otop] = pv
+ }
+ op = otop + 1
+ }
+
+ # Advance the line index.
+ x1 = x2 + 1
+
+ case I_SH:
+ pv = (int(ll_src[ip+1]) * I_SHIFT) + data
+ skipword = true
+ case I_IH:
+ pv = pv + data
+ case I_DH:
+ pv = pv - data
+ case I_IS:
+ pv = pv + data
+ goto putpix_
+ case I_DS:
+ pv = pv - data
+putpix_
+ if (x1 >= xs && x1 <= xe) {
+ px_dst[op] = pv
+ op = op + 1
+ }
+ x1 = x1 + 1
+ }
+
+ if (x1 > xe)
+ break
+ }
+
+ # Zero any remaining output range.
+ do i = op, npix
+ px_dst[i] = 0
+
+ return (npix)
+end
diff --git a/sys/plio/tf/pll2pl.x b/sys/plio/tf/pll2pl.x
new file mode 100644
index 00000000..9863019b
--- /dev/null
+++ b/sys/plio/tf/pll2pl.x
@@ -0,0 +1,105 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plio.h>
+
+# PL_L2P -- Convert a line list to a pixel array. The number of pixels output
+# (always npix) is returned as the function value.
+
+int procedure pl_l2pl (ll_src, xs, px_dst, npix)
+
+short ll_src[ARB] #I input line list
+int xs #I starting index in ll_src
+long px_dst[ARB] #O output pixel array
+int npix #I number of pixels to convert
+
+long pv
+bool skipword
+int opcode, data, ll_len, ll_first
+int x1, x2, i1, i2, xe, np, ip, op, otop, i
+define putpix_ 91
+
+begin
+ # Support old format line lists.
+ if (LL_OLDFORMAT(ll_src)) {
+ ll_len = OLL_LEN(ll_src)
+ ll_first = OLL_FIRST
+ } else {
+ ll_len = LL_LEN(ll_src)
+ ll_first = LL_FIRST(ll_src)
+ }
+
+ # No pixels?
+ if (npix <= 0 || ll_len <= 0)
+ return (0)
+
+ xe = xs + npix - 1
+ skipword = false
+ op = 1
+ x1 = 1
+ pv = 1
+
+ do ip = ll_first, ll_len {
+ if (skipword) {
+ skipword = false
+ next
+ }
+
+ opcode = I_OPCODE(ll_src[ip])
+ data = I_DATA(ll_src[ip])
+
+ switch (opcode) {
+ case I_ZN, I_HN, I_PN:
+ # Determine inbounds region of segment.
+ x2 = x1 + data - 1
+ i1 = max (x1, xs)
+ i2 = min (x2, xe)
+
+ # Process segment if any region is inbounds.
+ np = i2 - i1 + 1
+ if (np > 0) {
+ otop = op + np - 1
+ if (opcode == I_HN) {
+ do i = op, otop
+ px_dst[i] = pv
+ } else {
+ do i = op, otop
+ px_dst[i] = 0
+ if (opcode == I_PN && i2 == x2)
+ px_dst[otop] = pv
+ }
+ op = otop + 1
+ }
+
+ # Advance the line index.
+ x1 = x2 + 1
+
+ case I_SH:
+ pv = (int(ll_src[ip+1]) * I_SHIFT) + data
+ skipword = true
+ case I_IH:
+ pv = pv + data
+ case I_DH:
+ pv = pv - data
+ case I_IS:
+ pv = pv + data
+ goto putpix_
+ case I_DS:
+ pv = pv - data
+putpix_
+ if (x1 >= xs && x1 <= xe) {
+ px_dst[op] = pv
+ op = op + 1
+ }
+ x1 = x1 + 1
+ }
+
+ if (x1 > xe)
+ break
+ }
+
+ # Zero any remaining output range.
+ do i = op, npix
+ px_dst[i] = 0
+
+ return (npix)
+end
diff --git a/sys/plio/tf/pll2ps.x b/sys/plio/tf/pll2ps.x
new file mode 100644
index 00000000..a853e5ba
--- /dev/null
+++ b/sys/plio/tf/pll2ps.x
@@ -0,0 +1,105 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plio.h>
+
+# PL_L2P -- Convert a line list to a pixel array. The number of pixels output
+# (always npix) is returned as the function value.
+
+int procedure pl_l2ps (ll_src, xs, px_dst, npix)
+
+short ll_src[ARB] #I input line list
+int xs #I starting index in ll_src
+short px_dst[ARB] #O output pixel array
+int npix #I number of pixels to convert
+
+short pv
+bool skipword
+int opcode, data, ll_len, ll_first
+int x1, x2, i1, i2, xe, np, ip, op, otop, i
+define putpix_ 91
+
+begin
+ # Support old format line lists.
+ if (LL_OLDFORMAT(ll_src)) {
+ ll_len = OLL_LEN(ll_src)
+ ll_first = OLL_FIRST
+ } else {
+ ll_len = LL_LEN(ll_src)
+ ll_first = LL_FIRST(ll_src)
+ }
+
+ # No pixels?
+ if (npix <= 0 || ll_len <= 0)
+ return (0)
+
+ xe = xs + npix - 1
+ skipword = false
+ op = 1
+ x1 = 1
+ pv = 1
+
+ do ip = ll_first, ll_len {
+ if (skipword) {
+ skipword = false
+ next
+ }
+
+ opcode = I_OPCODE(ll_src[ip])
+ data = I_DATA(ll_src[ip])
+
+ switch (opcode) {
+ case I_ZN, I_HN, I_PN:
+ # Determine inbounds region of segment.
+ x2 = x1 + data - 1
+ i1 = max (x1, xs)
+ i2 = min (x2, xe)
+
+ # Process segment if any region is inbounds.
+ np = i2 - i1 + 1
+ if (np > 0) {
+ otop = op + np - 1
+ if (opcode == I_HN) {
+ do i = op, otop
+ px_dst[i] = pv
+ } else {
+ do i = op, otop
+ px_dst[i] = 0
+ if (opcode == I_PN && i2 == x2)
+ px_dst[otop] = pv
+ }
+ op = otop + 1
+ }
+
+ # Advance the line index.
+ x1 = x2 + 1
+
+ case I_SH:
+ pv = (int(ll_src[ip+1]) * I_SHIFT) + data
+ skipword = true
+ case I_IH:
+ pv = pv + data
+ case I_DH:
+ pv = pv - data
+ case I_IS:
+ pv = pv + data
+ goto putpix_
+ case I_DS:
+ pv = pv - data
+putpix_
+ if (x1 >= xs && x1 <= xe) {
+ px_dst[op] = pv
+ op = op + 1
+ }
+ x1 = x1 + 1
+ }
+
+ if (x1 > xe)
+ break
+ }
+
+ # Zero any remaining output range.
+ do i = op, npix
+ px_dst[i] = 0
+
+ return (npix)
+end
diff --git a/sys/plio/tf/pll2ri.x b/sys/plio/tf/pll2ri.x
new file mode 100644
index 00000000..431b97e2
--- /dev/null
+++ b/sys/plio/tf/pll2ri.x
@@ -0,0 +1,117 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plset.h>
+include <plio.h>
+
+# PL_L2R -- Convert a line list to a range list. The length of the output
+# range list is returned as the function value.
+
+int procedure pl_l2ri (ll_src, xs, rl, npix)
+
+short ll_src[ARB] #I input line list
+int xs #I starting index in ll_src
+int rl[3,ARB] #O output range list
+int npix #I number of pixels to convert
+
+int pv, hi
+bool skipword
+int opcode, data, ll_len, ll_first
+int x1, x2, i1, i2, xe, np, rn, ip
+define range_ 91
+define putrange_ 92
+
+begin
+ # Support old format line lists.
+ if (LL_OLDFORMAT(ll_src)) {
+ ll_len = OLL_LEN(ll_src)
+ ll_first = OLL_FIRST
+ } else {
+ ll_len = LL_LEN(ll_src)
+ ll_first = LL_FIRST(ll_src)
+ }
+
+ # No pixels?
+ if (npix <= 0 || ll_len <= 0)
+ return (0)
+
+ rn = RL_FIRST
+ xe = xs + npix - 1
+ skipword = false
+ x1 = 1
+ hi = 1
+
+ do ip = ll_first, ll_len {
+ if (skipword) {
+ skipword = false
+ next
+ }
+
+ opcode = I_OPCODE(ll_src[ip])
+ data = I_DATA(ll_src[ip])
+
+ switch (opcode) {
+ case I_ZN:
+ pv = 0
+ goto range_
+ case I_HN:
+ pv = hi
+range_
+ # Determine inbounds region of segment.
+ x2 = x1 + data - 1
+ i1 = max (x1, xs)
+ i2 = min (x2, xe)
+ np = i2 - i1 + 1
+ x1 = x2 + 1
+
+ case I_PN:
+ pv = hi
+ x2 = x1 + data - 1
+ if (x2 < xs || x2 > xe)
+ np = 0
+ else {
+ i1 = x2
+ np = 1
+ }
+ x1 = x2 + 1
+
+ case I_SH:
+ hi = (int(ll_src[ip+1]) * I_SHIFT) + data
+ skipword = true
+ next
+ case I_IH:
+ hi = hi + data
+ next
+ case I_DH:
+ hi = hi - data
+ next
+
+ case I_IS, I_DS:
+ if (opcode == I_IS)
+ hi = hi + data
+ else
+ hi = hi - data
+
+ i1 = max (x1, xs)
+ i2 = min (x1, xe)
+ np = i2 - i1 + 1
+ x1 = x1 + 1
+ pv = hi
+ }
+
+ # Output a range entry?
+ if (np > 0 && pv > 0) {
+ rl[1,rn] = i1
+ rl[2,rn] = np
+ rl[3,rn] = pv
+ rn = rn + 1
+ }
+
+ if (x1 > xe)
+ break
+ }
+
+ RL_LEN(rl) = rn - 1
+ RL_AXLEN(rl) = npix
+
+ return (rn - 1)
+end
diff --git a/sys/plio/tf/pll2rl.x b/sys/plio/tf/pll2rl.x
new file mode 100644
index 00000000..0ff4ce4b
--- /dev/null
+++ b/sys/plio/tf/pll2rl.x
@@ -0,0 +1,117 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plset.h>
+include <plio.h>
+
+# PL_L2R -- Convert a line list to a range list. The length of the output
+# range list is returned as the function value.
+
+int procedure pl_l2rl (ll_src, xs, rl, npix)
+
+short ll_src[ARB] #I input line list
+int xs #I starting index in ll_src
+long rl[3,ARB] #O output range list
+int npix #I number of pixels to convert
+
+int pv, hi
+bool skipword
+int opcode, data, ll_len, ll_first
+int x1, x2, i1, i2, xe, np, rn, ip
+define range_ 91
+define putrange_ 92
+
+begin
+ # Support old format line lists.
+ if (LL_OLDFORMAT(ll_src)) {
+ ll_len = OLL_LEN(ll_src)
+ ll_first = OLL_FIRST
+ } else {
+ ll_len = LL_LEN(ll_src)
+ ll_first = LL_FIRST(ll_src)
+ }
+
+ # No pixels?
+ if (npix <= 0 || ll_len <= 0)
+ return (0)
+
+ rn = RL_FIRST
+ xe = xs + npix - 1
+ skipword = false
+ x1 = 1
+ hi = 1
+
+ do ip = ll_first, ll_len {
+ if (skipword) {
+ skipword = false
+ next
+ }
+
+ opcode = I_OPCODE(ll_src[ip])
+ data = I_DATA(ll_src[ip])
+
+ switch (opcode) {
+ case I_ZN:
+ pv = 0
+ goto range_
+ case I_HN:
+ pv = hi
+range_
+ # Determine inbounds region of segment.
+ x2 = x1 + data - 1
+ i1 = max (x1, xs)
+ i2 = min (x2, xe)
+ np = i2 - i1 + 1
+ x1 = x2 + 1
+
+ case I_PN:
+ pv = hi
+ x2 = x1 + data - 1
+ if (x2 < xs || x2 > xe)
+ np = 0
+ else {
+ i1 = x2
+ np = 1
+ }
+ x1 = x2 + 1
+
+ case I_SH:
+ hi = (int(ll_src[ip+1]) * I_SHIFT) + data
+ skipword = true
+ next
+ case I_IH:
+ hi = hi + data
+ next
+ case I_DH:
+ hi = hi - data
+ next
+
+ case I_IS, I_DS:
+ if (opcode == I_IS)
+ hi = hi + data
+ else
+ hi = hi - data
+
+ i1 = max (x1, xs)
+ i2 = min (x1, xe)
+ np = i2 - i1 + 1
+ x1 = x1 + 1
+ pv = hi
+ }
+
+ # Output a range entry?
+ if (np > 0 && pv > 0) {
+ rl[1,rn] = i1
+ rl[2,rn] = np
+ rl[3,rn] = pv
+ rn = rn + 1
+ }
+
+ if (x1 > xe)
+ break
+ }
+
+ RL_LEN(rl) = rn - 1
+ RL_AXLEN(rl) = npix
+
+ return (rn - 1)
+end
diff --git a/sys/plio/tf/pll2rs.x b/sys/plio/tf/pll2rs.x
new file mode 100644
index 00000000..a0852774
--- /dev/null
+++ b/sys/plio/tf/pll2rs.x
@@ -0,0 +1,117 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plset.h>
+include <plio.h>
+
+# PL_L2R -- Convert a line list to a range list. The length of the output
+# range list is returned as the function value.
+
+int procedure pl_l2rs (ll_src, xs, rl, npix)
+
+short ll_src[ARB] #I input line list
+int xs #I starting index in ll_src
+short rl[3,ARB] #O output range list
+int npix #I number of pixels to convert
+
+int pv, hi
+bool skipword
+int opcode, data, ll_len, ll_first
+int x1, x2, i1, i2, xe, np, rn, ip
+define range_ 91
+define putrange_ 92
+
+begin
+ # Support old format line lists.
+ if (LL_OLDFORMAT(ll_src)) {
+ ll_len = OLL_LEN(ll_src)
+ ll_first = OLL_FIRST
+ } else {
+ ll_len = LL_LEN(ll_src)
+ ll_first = LL_FIRST(ll_src)
+ }
+
+ # No pixels?
+ if (npix <= 0 || ll_len <= 0)
+ return (0)
+
+ rn = RL_FIRST
+ xe = xs + npix - 1
+ skipword = false
+ x1 = 1
+ hi = 1
+
+ do ip = ll_first, ll_len {
+ if (skipword) {
+ skipword = false
+ next
+ }
+
+ opcode = I_OPCODE(ll_src[ip])
+ data = I_DATA(ll_src[ip])
+
+ switch (opcode) {
+ case I_ZN:
+ pv = 0
+ goto range_
+ case I_HN:
+ pv = hi
+range_
+ # Determine inbounds region of segment.
+ x2 = x1 + data - 1
+ i1 = max (x1, xs)
+ i2 = min (x2, xe)
+ np = i2 - i1 + 1
+ x1 = x2 + 1
+
+ case I_PN:
+ pv = hi
+ x2 = x1 + data - 1
+ if (x2 < xs || x2 > xe)
+ np = 0
+ else {
+ i1 = x2
+ np = 1
+ }
+ x1 = x2 + 1
+
+ case I_SH:
+ hi = (int(ll_src[ip+1]) * I_SHIFT) + data
+ skipword = true
+ next
+ case I_IH:
+ hi = hi + data
+ next
+ case I_DH:
+ hi = hi - data
+ next
+
+ case I_IS, I_DS:
+ if (opcode == I_IS)
+ hi = hi + data
+ else
+ hi = hi - data
+
+ i1 = max (x1, xs)
+ i2 = min (x1, xe)
+ np = i2 - i1 + 1
+ x1 = x1 + 1
+ pv = hi
+ }
+
+ # Output a range entry?
+ if (np > 0 && pv > 0) {
+ rl[1,rn] = i1
+ rl[2,rn] = np
+ rl[3,rn] = pv
+ rn = rn + 1
+ }
+
+ if (x1 > xe)
+ break
+ }
+
+ RL_LEN(rl) = rn - 1
+ RL_AXLEN(rl) = npix
+
+ return (rn - 1)
+end
diff --git a/sys/plio/tf/plp2li.x b/sys/plio/tf/plp2li.x
new file mode 100644
index 00000000..58b3a8b5
--- /dev/null
+++ b/sys/plio/tf/plp2li.x
@@ -0,0 +1,126 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plio.h>
+
+# PL_P2L -- Convert a pixel array to a line list. The length of the list is
+# returned as the function value.
+
+int procedure pl_p2li (px_src, xs, ll_dst, npix)
+
+int px_src[ARB] #I input pixel array
+int xs #I starting index in pixbuf
+short ll_dst[ARB] #O destination line list
+int npix #I number of pixels to convert
+
+int hi, pv, nv, zero
+int xe, x1, iz, ip, op, np, nz, dv, v
+define done_ 91
+
+begin
+ # No input pixels?
+ if (npix <= 0)
+ return (0)
+
+ # Initialize the linelist header.
+ LL_VERSION(ll_dst) = LL_CURVERSION
+ LL_HDRLEN(ll_dst) = LL_CURHDRLEN
+ LL_NREFS(ll_dst) = 0
+ LL_SETBLEN(ll_dst,0)
+
+ xe = xs + npix - 1
+ op = LL_CURHDRLEN + 1
+
+ # Pack the pixel array into a line list. This is done by scanning
+ # the pixel list for successive ranges of pixels of constant nonzero
+ # value, where each range is described as follows:
+
+ zero = 0
+ pv = max (zero, px_src[xs]) # pixel value of current range
+ x1 = xs # start index of current range
+ iz = xs # start index of range of zeros
+ hi = 1 # current high value
+
+ # Process the data array.
+ do ip = xs, xe {
+ if (ip < xe) {
+ # Get the next pixel value, loop again if same as previous one.
+ nv = max (zero, px_src[ip+1])
+ if (nv == pv)
+ next
+
+ # If current range is zero, loop again to get nonzero range.
+ if (pv == 0) {
+ pv = nv
+ x1 = ip + 1
+ next
+ }
+ } else if (pv == 0)
+ x1 = xe + 1
+
+ # Encode an instruction to regenerate the current range I0-IP
+ # of N data values of nonzero level PV. In the most complex case
+ # we must update the high value and output a range of zeros,
+ # followed by a range of NP high values. If NP is 1, we can
+ # probably use a PN or [ID]S instruction to save space.
+
+ np = ip - x1 + 1
+ nz = x1 - iz
+
+ # Change the high value?
+ if (pv > 0) {
+ dv = pv - hi
+ if (dv != 0) {
+ # Output IH or DH instruction?
+ hi = pv
+ if (abs(dv) > I_DATAMAX) {
+ ll_dst[op] = M_SH + and (int(pv), I_DATAMAX)
+ op = op + 1
+ ll_dst[op] = pv / I_SHIFT
+ op = op + 1
+ } else {
+ if (dv < 0)
+ ll_dst[op] = M_DH + (-dv)
+ else
+ ll_dst[op] = M_IH + dv
+ op = op + 1
+
+ # Convert to IS or DS if range is a single pixel.
+ if (np == 1 && nz == 0) {
+ v = ll_dst[op-1]
+ ll_dst[op-1] = or (v, M_MOVE)
+ goto done_
+ }
+ }
+ }
+ }
+
+ # Output range of zeros to catch up to current range?
+ # The I_DATAMAX-1 limit is to allow adding M_PN+1 without
+ # overflowing the range of the data segment.
+ if (nz > 0) {
+ # Output the ZN instruction.
+ for (; nz > 0; nz = nz - (I_DATAMAX-1)) {
+ ll_dst[op] = M_ZN + min(I_DATAMAX-1,nz)
+ op = op + 1
+ }
+ # Convert to PN if range is a single pixel.
+ if (np == 1 && pv > 0) {
+ ll_dst[op-1] = ll_dst[op-1] + M_PN + 1
+ goto done_
+ }
+ }
+
+ # The only thing left is the HN instruction if we get here.
+ for (; np > 0; np = np - I_DATAMAX) {
+ ll_dst[op] = M_HN + min(I_DATAMAX,np)
+ op = op + 1
+ }
+done_
+ x1 = ip + 1
+ iz = x1
+ pv = nv
+ }
+
+ LL_SETLEN(ll_dst, op - 1)
+ return (op - 1)
+end
diff --git a/sys/plio/tf/plp2ll.x b/sys/plio/tf/plp2ll.x
new file mode 100644
index 00000000..fa4a7d13
--- /dev/null
+++ b/sys/plio/tf/plp2ll.x
@@ -0,0 +1,126 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plio.h>
+
+# PL_P2L -- Convert a pixel array to a line list. The length of the list is
+# returned as the function value.
+
+int procedure pl_p2ll (px_src, xs, ll_dst, npix)
+
+long px_src[ARB] #I input pixel array
+int xs #I starting index in pixbuf
+short ll_dst[ARB] #O destination line list
+int npix #I number of pixels to convert
+
+long hi, pv, nv, zero
+int xe, x1, iz, ip, op, np, nz, dv, v
+define done_ 91
+
+begin
+ # No input pixels?
+ if (npix <= 0)
+ return (0)
+
+ # Initialize the linelist header.
+ LL_VERSION(ll_dst) = LL_CURVERSION
+ LL_HDRLEN(ll_dst) = LL_CURHDRLEN
+ LL_NREFS(ll_dst) = 0
+ LL_SETBLEN(ll_dst,0)
+
+ xe = xs + npix - 1
+ op = LL_CURHDRLEN + 1
+
+ # Pack the pixel array into a line list. This is done by scanning
+ # the pixel list for successive ranges of pixels of constant nonzero
+ # value, where each range is described as follows:
+
+ zero = 0
+ pv = max (zero, px_src[xs]) # pixel value of current range
+ x1 = xs # start index of current range
+ iz = xs # start index of range of zeros
+ hi = 1 # current high value
+
+ # Process the data array.
+ do ip = xs, xe {
+ if (ip < xe) {
+ # Get the next pixel value, loop again if same as previous one.
+ nv = max (zero, px_src[ip+1])
+ if (nv == pv)
+ next
+
+ # If current range is zero, loop again to get nonzero range.
+ if (pv == 0) {
+ pv = nv
+ x1 = ip + 1
+ next
+ }
+ } else if (pv == 0)
+ x1 = xe + 1
+
+ # Encode an instruction to regenerate the current range I0-IP
+ # of N data values of nonzero level PV. In the most complex case
+ # we must update the high value and output a range of zeros,
+ # followed by a range of NP high values. If NP is 1, we can
+ # probably use a PN or [ID]S instruction to save space.
+
+ np = ip - x1 + 1
+ nz = x1 - iz
+
+ # Change the high value?
+ if (pv > 0) {
+ dv = pv - hi
+ if (dv != 0) {
+ # Output IH or DH instruction?
+ hi = pv
+ if (abs(dv) > I_DATAMAX) {
+ ll_dst[op] = M_SH + and (int(pv), I_DATAMAX)
+ op = op + 1
+ ll_dst[op] = pv / I_SHIFT
+ op = op + 1
+ } else {
+ if (dv < 0)
+ ll_dst[op] = M_DH + (-dv)
+ else
+ ll_dst[op] = M_IH + dv
+ op = op + 1
+
+ # Convert to IS or DS if range is a single pixel.
+ if (np == 1 && nz == 0) {
+ v = ll_dst[op-1]
+ ll_dst[op-1] = or (v, M_MOVE)
+ goto done_
+ }
+ }
+ }
+ }
+
+ # Output range of zeros to catch up to current range?
+ # The I_DATAMAX-1 limit is to allow adding M_PN+1 without
+ # overflowing the range of the data segment.
+ if (nz > 0) {
+ # Output the ZN instruction.
+ for (; nz > 0; nz = nz - (I_DATAMAX-1)) {
+ ll_dst[op] = M_ZN + min(I_DATAMAX-1,nz)
+ op = op + 1
+ }
+ # Convert to PN if range is a single pixel.
+ if (np == 1 && pv > 0) {
+ ll_dst[op-1] = ll_dst[op-1] + M_PN + 1
+ goto done_
+ }
+ }
+
+ # The only thing left is the HN instruction if we get here.
+ for (; np > 0; np = np - I_DATAMAX) {
+ ll_dst[op] = M_HN + min(I_DATAMAX,np)
+ op = op + 1
+ }
+done_
+ x1 = ip + 1
+ iz = x1
+ pv = nv
+ }
+
+ LL_SETLEN(ll_dst, op - 1)
+ return (op - 1)
+end
diff --git a/sys/plio/tf/plp2ls.x b/sys/plio/tf/plp2ls.x
new file mode 100644
index 00000000..327778dc
--- /dev/null
+++ b/sys/plio/tf/plp2ls.x
@@ -0,0 +1,126 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plio.h>
+
+# PL_P2L -- Convert a pixel array to a line list. The length of the list is
+# returned as the function value.
+
+int procedure pl_p2ls (px_src, xs, ll_dst, npix)
+
+short px_src[ARB] #I input pixel array
+int xs #I starting index in pixbuf
+short ll_dst[ARB] #O destination line list
+int npix #I number of pixels to convert
+
+short hi, pv, nv, zero
+int xe, x1, iz, ip, op, np, nz, dv, v
+define done_ 91
+
+begin
+ # No input pixels?
+ if (npix <= 0)
+ return (0)
+
+ # Initialize the linelist header.
+ LL_VERSION(ll_dst) = LL_CURVERSION
+ LL_HDRLEN(ll_dst) = LL_CURHDRLEN
+ LL_NREFS(ll_dst) = 0
+ LL_SETBLEN(ll_dst,0)
+
+ xe = xs + npix - 1
+ op = LL_CURHDRLEN + 1
+
+ # Pack the pixel array into a line list. This is done by scanning
+ # the pixel list for successive ranges of pixels of constant nonzero
+ # value, where each range is described as follows:
+
+ zero = 0
+ pv = max (zero, px_src[xs]) # pixel value of current range
+ x1 = xs # start index of current range
+ iz = xs # start index of range of zeros
+ hi = 1 # current high value
+
+ # Process the data array.
+ do ip = xs, xe {
+ if (ip < xe) {
+ # Get the next pixel value, loop again if same as previous one.
+ nv = max (zero, px_src[ip+1])
+ if (nv == pv)
+ next
+
+ # If current range is zero, loop again to get nonzero range.
+ if (pv == 0) {
+ pv = nv
+ x1 = ip + 1
+ next
+ }
+ } else if (pv == 0)
+ x1 = xe + 1
+
+ # Encode an instruction to regenerate the current range I0-IP
+ # of N data values of nonzero level PV. In the most complex case
+ # we must update the high value and output a range of zeros,
+ # followed by a range of NP high values. If NP is 1, we can
+ # probably use a PN or [ID]S instruction to save space.
+
+ np = ip - x1 + 1
+ nz = x1 - iz
+
+ # Change the high value?
+ if (pv > 0) {
+ dv = pv - hi
+ if (dv != 0) {
+ # Output IH or DH instruction?
+ hi = pv
+ if (abs(dv) > I_DATAMAX) {
+ ll_dst[op] = M_SH + and (int(pv), I_DATAMAX)
+ op = op + 1
+ ll_dst[op] = pv / I_SHIFT
+ op = op + 1
+ } else {
+ if (dv < 0)
+ ll_dst[op] = M_DH + (-dv)
+ else
+ ll_dst[op] = M_IH + dv
+ op = op + 1
+
+ # Convert to IS or DS if range is a single pixel.
+ if (np == 1 && nz == 0) {
+ v = ll_dst[op-1]
+ ll_dst[op-1] = or (v, M_MOVE)
+ goto done_
+ }
+ }
+ }
+ }
+
+ # Output range of zeros to catch up to current range?
+ # The I_DATAMAX-1 limit is to allow adding M_PN+1 without
+ # overflowing the range of the data segment.
+ if (nz > 0) {
+ # Output the ZN instruction.
+ for (; nz > 0; nz = nz - (I_DATAMAX-1)) {
+ ll_dst[op] = M_ZN + min(I_DATAMAX-1,nz)
+ op = op + 1
+ }
+ # Convert to PN if range is a single pixel.
+ if (np == 1 && pv > 0) {
+ ll_dst[op-1] = ll_dst[op-1] + M_PN + 1
+ goto done_
+ }
+ }
+
+ # The only thing left is the HN instruction if we get here.
+ for (; np > 0; np = np - I_DATAMAX) {
+ ll_dst[op] = M_HN + min(I_DATAMAX,np)
+ op = op + 1
+ }
+done_
+ x1 = ip + 1
+ iz = x1
+ pv = nv
+ }
+
+ LL_SETLEN(ll_dst, op - 1)
+ return (op - 1)
+end
diff --git a/sys/plio/tf/plp2ri.x b/sys/plio/tf/plp2ri.x
new file mode 100644
index 00000000..64f4f1eb
--- /dev/null
+++ b/sys/plio/tf/plp2ri.x
@@ -0,0 +1,71 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plset.h>
+include <plio.h>
+
+# PL_P2R -- Convert a pixel array to a range list. The length of the output
+# range list is returned as the function value.
+
+int procedure pl_p2ri (px_src, xs, rl, npix)
+
+int px_src[ARB] #I input pixel array
+int xs #I starting index in pixbuf
+int rl[3,ARB] #O destination range list
+int npix #I number of pixels to convert
+
+int hi, pv, zero
+int xe, x1, np, rn, nv, ip
+define done_ 91
+
+begin
+ # No input pixels?
+ if (npix <= 0)
+ return (0)
+
+ xe = xs + npix - 1
+ rn = RL_FIRST
+
+ # Pack the pixel array into a range list. This is done by scanning
+ # the pixel list for successive ranges of pixels of constant nonzero
+ # value, where each range is described as follows:
+
+ zero = 0
+ pv = max (zero, px_src[xs]) # pixel value of current range
+ x1 = xs # start index of current range
+ hi = 1 # current high value
+
+ # Process the data array.
+ do ip = xs, xe {
+ if (ip < xe) {
+ # Get the next pixel value, loop again if same as previous one.
+ nv = max (zero, px_src[ip+1])
+ if (nv == pv)
+ next
+
+ # If current range is zero, loop again to get nonzero range.
+ if (pv == 0) {
+ pv = nv
+ x1 = ip + 1
+ next
+ }
+ }
+
+ np = ip - x1 + 1
+
+ # Output the new range.
+ if (pv > 0) {
+ rl[1,rn] = x1
+ rl[2,rn] = np
+ rl[3,rn] = pv
+ rn = rn + 1
+ }
+
+ x1 = ip + 1
+ pv = nv
+ }
+
+ RL_LEN(rl) = rn - 1
+ RL_AXLEN(rl) = npix
+
+ return (rn - 1)
+end
diff --git a/sys/plio/tf/plp2rl.x b/sys/plio/tf/plp2rl.x
new file mode 100644
index 00000000..574faad9
--- /dev/null
+++ b/sys/plio/tf/plp2rl.x
@@ -0,0 +1,71 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plset.h>
+include <plio.h>
+
+# PL_P2R -- Convert a pixel array to a range list. The length of the output
+# range list is returned as the function value.
+
+int procedure pl_p2rl (px_src, xs, rl, npix)
+
+long px_src[ARB] #I input pixel array
+int xs #I starting index in pixbuf
+long rl[3,ARB] #O destination range list
+int npix #I number of pixels to convert
+
+long hi, pv, zero
+int xe, x1, np, rn, nv, ip
+define done_ 91
+
+begin
+ # No input pixels?
+ if (npix <= 0)
+ return (0)
+
+ xe = xs + npix - 1
+ rn = RL_FIRST
+
+ # Pack the pixel array into a range list. This is done by scanning
+ # the pixel list for successive ranges of pixels of constant nonzero
+ # value, where each range is described as follows:
+
+ zero = 0
+ pv = max (zero, px_src[xs]) # pixel value of current range
+ x1 = xs # start index of current range
+ hi = 1 # current high value
+
+ # Process the data array.
+ do ip = xs, xe {
+ if (ip < xe) {
+ # Get the next pixel value, loop again if same as previous one.
+ nv = max (zero, px_src[ip+1])
+ if (nv == pv)
+ next
+
+ # If current range is zero, loop again to get nonzero range.
+ if (pv == 0) {
+ pv = nv
+ x1 = ip + 1
+ next
+ }
+ }
+
+ np = ip - x1 + 1
+
+ # Output the new range.
+ if (pv > 0) {
+ rl[1,rn] = x1
+ rl[2,rn] = np
+ rl[3,rn] = pv
+ rn = rn + 1
+ }
+
+ x1 = ip + 1
+ pv = nv
+ }
+
+ RL_LEN(rl) = rn - 1
+ RL_AXLEN(rl) = npix
+
+ return (rn - 1)
+end
diff --git a/sys/plio/tf/plp2rs.x b/sys/plio/tf/plp2rs.x
new file mode 100644
index 00000000..da082f47
--- /dev/null
+++ b/sys/plio/tf/plp2rs.x
@@ -0,0 +1,71 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plset.h>
+include <plio.h>
+
+# PL_P2R -- Convert a pixel array to a range list. The length of the output
+# range list is returned as the function value.
+
+int procedure pl_p2rs (px_src, xs, rl, npix)
+
+short px_src[ARB] #I input pixel array
+int xs #I starting index in pixbuf
+short rl[3,ARB] #O destination range list
+int npix #I number of pixels to convert
+
+short hi, pv, zero
+int xe, x1, np, rn, nv, ip
+define done_ 91
+
+begin
+ # No input pixels?
+ if (npix <= 0)
+ return (0)
+
+ xe = xs + npix - 1
+ rn = RL_FIRST
+
+ # Pack the pixel array into a range list. This is done by scanning
+ # the pixel list for successive ranges of pixels of constant nonzero
+ # value, where each range is described as follows:
+
+ zero = 0
+ pv = max (zero, px_src[xs]) # pixel value of current range
+ x1 = xs # start index of current range
+ hi = 1 # current high value
+
+ # Process the data array.
+ do ip = xs, xe {
+ if (ip < xe) {
+ # Get the next pixel value, loop again if same as previous one.
+ nv = max (zero, px_src[ip+1])
+ if (nv == pv)
+ next
+
+ # If current range is zero, loop again to get nonzero range.
+ if (pv == 0) {
+ pv = nv
+ x1 = ip + 1
+ next
+ }
+ }
+
+ np = ip - x1 + 1
+
+ # Output the new range.
+ if (pv > 0) {
+ rl[1,rn] = x1
+ rl[2,rn] = np
+ rl[3,rn] = pv
+ rn = rn + 1
+ }
+
+ x1 = ip + 1
+ pv = nv
+ }
+
+ RL_LEN(rl) = rn - 1
+ RL_AXLEN(rl) = npix
+
+ return (rn - 1)
+end
diff --git a/sys/plio/tf/plplpi.x b/sys/plio/tf/plplpi.x
new file mode 100644
index 00000000..26c094d4
--- /dev/null
+++ b/sys/plio/tf/plplpi.x
@@ -0,0 +1,41 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plio.h>
+
+# PL_PLP -- Put a line segment input as a pixel array to a mask, applying the
+# given ROP to combine the line segment with the existing line of the mask.
+
+procedure pl_plpi (pl, v, px_src, px_depth, npix, rop)
+
+pointer pl #I mask descriptor
+long v[PL_MAXDIM] #I vector coords of line segment
+int px_src[ARB] #I input pixel array
+int px_depth #I pixel depth, bits
+int npix #I number of pixels to be set
+int rop #I rasterop
+
+int ll_len
+pointer sp, ll_src, ll_out, ll_dst
+pointer pl_access()
+int pl_p2li()
+errchk pl_access
+
+begin
+ call smark (sp)
+ call salloc (ll_src, LL_MAXLEN(pl), TY_SHORT)
+
+ # Convert the pixel array to a line list.
+ ll_len = pl_p2li (px_src, 1, Mems[ll_src], npix)
+
+ if (!R_NEED_DST(rop) && v[1] == 1 && npix == PL_AXLEN(pl,1))
+ call pl_update (pl, v, Mems[ll_src])
+ else {
+ call salloc (ll_out, LL_MAXLEN(pl), TY_SHORT)
+ ll_dst = pl_access (pl,v)
+ call pl_linerop (Mems[ll_src], 1, PL_MAXVAL(pl), Mems[ll_dst], v[1],
+ MV(px_depth), Mems[ll_out], npix, rop)
+ call pl_update (pl, v, Mems[ll_out])
+ }
+
+ call sfree (sp)
+end
diff --git a/sys/plio/tf/plplpl.x b/sys/plio/tf/plplpl.x
new file mode 100644
index 00000000..85a11304
--- /dev/null
+++ b/sys/plio/tf/plplpl.x
@@ -0,0 +1,41 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plio.h>
+
+# PL_PLP -- Put a line segment input as a pixel array to a mask, applying the
+# given ROP to combine the line segment with the existing line of the mask.
+
+procedure pl_plpl (pl, v, px_src, px_depth, npix, rop)
+
+pointer pl #I mask descriptor
+long v[PL_MAXDIM] #I vector coords of line segment
+long px_src[ARB] #I input pixel array
+int px_depth #I pixel depth, bits
+int npix #I number of pixels to be set
+int rop #I rasterop
+
+int ll_len
+pointer sp, ll_src, ll_out, ll_dst
+pointer pl_access()
+int pl_p2ll()
+errchk pl_access
+
+begin
+ call smark (sp)
+ call salloc (ll_src, LL_MAXLEN(pl), TY_SHORT)
+
+ # Convert the pixel array to a line list.
+ ll_len = pl_p2ll (px_src, 1, Mems[ll_src], npix)
+
+ if (!R_NEED_DST(rop) && v[1] == 1 && npix == PL_AXLEN(pl,1))
+ call pl_update (pl, v, Mems[ll_src])
+ else {
+ call salloc (ll_out, LL_MAXLEN(pl), TY_SHORT)
+ ll_dst = pl_access (pl,v)
+ call pl_linerop (Mems[ll_src], 1, PL_MAXVAL(pl), Mems[ll_dst], v[1],
+ MV(px_depth), Mems[ll_out], npix, rop)
+ call pl_update (pl, v, Mems[ll_out])
+ }
+
+ call sfree (sp)
+end
diff --git a/sys/plio/tf/plplps.x b/sys/plio/tf/plplps.x
new file mode 100644
index 00000000..b693c90e
--- /dev/null
+++ b/sys/plio/tf/plplps.x
@@ -0,0 +1,41 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plio.h>
+
+# PL_PLP -- Put a line segment input as a pixel array to a mask, applying the
+# given ROP to combine the line segment with the existing line of the mask.
+
+procedure pl_plps (pl, v, px_src, px_depth, npix, rop)
+
+pointer pl #I mask descriptor
+long v[PL_MAXDIM] #I vector coords of line segment
+short px_src[ARB] #I input pixel array
+int px_depth #I pixel depth, bits
+int npix #I number of pixels to be set
+int rop #I rasterop
+
+int ll_len
+pointer sp, ll_src, ll_out, ll_dst
+pointer pl_access()
+int pl_p2ls()
+errchk pl_access
+
+begin
+ call smark (sp)
+ call salloc (ll_src, LL_MAXLEN(pl), TY_SHORT)
+
+ # Convert the pixel array to a line list.
+ ll_len = pl_p2ls (px_src, 1, Mems[ll_src], npix)
+
+ if (!R_NEED_DST(rop) && v[1] == 1 && npix == PL_AXLEN(pl,1))
+ call pl_update (pl, v, Mems[ll_src])
+ else {
+ call salloc (ll_out, LL_MAXLEN(pl), TY_SHORT)
+ ll_dst = pl_access (pl,v)
+ call pl_linerop (Mems[ll_src], 1, PL_MAXVAL(pl), Mems[ll_dst], v[1],
+ MV(px_depth), Mems[ll_out], npix, rop)
+ call pl_update (pl, v, Mems[ll_out])
+ }
+
+ call sfree (sp)
+end
diff --git a/sys/plio/tf/plplri.x b/sys/plio/tf/plplri.x
new file mode 100644
index 00000000..433f9a88
--- /dev/null
+++ b/sys/plio/tf/plplri.x
@@ -0,0 +1,41 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plio.h>
+
+# PL_PLR -- Put a line segment input as a range list to a mask, applying the
+# given ROP to combine the line segment with the existing line of the mask.
+
+procedure pl_plri (pl, v, rl_src, rl_depth, npix, rop)
+
+pointer pl #I mask descriptor
+long v[PL_MAXDIM] #I vector coords of line segment
+int rl_src[ARB] #I input range list
+int rl_depth #I range list depth, bits
+int npix #I number of pixels to be set
+int rop #I rasterop
+
+int ll_len
+pointer sp, ll_src, ll_out, ll_dst
+pointer pl_access()
+int pl_r2li()
+errchk pl_access
+
+begin
+ call smark (sp)
+ call salloc (ll_src, LL_MAXLEN(pl), TY_SHORT)
+
+ # Convert the range list to a line list.
+ ll_len = pl_r2li (rl_src, 1, Mems[ll_src], npix)
+
+ if (!R_NEED_DST(rop) && v[1] == 1 && npix == PL_AXLEN(pl,1))
+ call pl_update (pl, v, Mems[ll_src])
+ else {
+ call salloc (ll_out, LL_MAXLEN(pl), TY_SHORT)
+ ll_dst = pl_access (pl,v)
+ call pl_linerop (Mems[ll_src], 1, PL_MAXVAL(pl), Mems[ll_dst], v[1],
+ MV(rl_depth), Mems[ll_out], npix, rop)
+ call pl_update (pl, v, Mems[ll_out])
+ }
+
+ call sfree (sp)
+end
diff --git a/sys/plio/tf/plplrl.x b/sys/plio/tf/plplrl.x
new file mode 100644
index 00000000..bf40b9ef
--- /dev/null
+++ b/sys/plio/tf/plplrl.x
@@ -0,0 +1,41 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plio.h>
+
+# PL_PLR -- Put a line segment input as a range list to a mask, applying the
+# given ROP to combine the line segment with the existing line of the mask.
+
+procedure pl_plrl (pl, v, rl_src, rl_depth, npix, rop)
+
+pointer pl #I mask descriptor
+long v[PL_MAXDIM] #I vector coords of line segment
+long rl_src[ARB] #I input range list
+int rl_depth #I range list depth, bits
+int npix #I number of pixels to be set
+int rop #I rasterop
+
+int ll_len
+pointer sp, ll_src, ll_out, ll_dst
+pointer pl_access()
+int pl_r2ll()
+errchk pl_access
+
+begin
+ call smark (sp)
+ call salloc (ll_src, LL_MAXLEN(pl), TY_SHORT)
+
+ # Convert the range list to a line list.
+ ll_len = pl_r2ll (rl_src, 1, Mems[ll_src], npix)
+
+ if (!R_NEED_DST(rop) && v[1] == 1 && npix == PL_AXLEN(pl,1))
+ call pl_update (pl, v, Mems[ll_src])
+ else {
+ call salloc (ll_out, LL_MAXLEN(pl), TY_SHORT)
+ ll_dst = pl_access (pl,v)
+ call pl_linerop (Mems[ll_src], 1, PL_MAXVAL(pl), Mems[ll_dst], v[1],
+ MV(rl_depth), Mems[ll_out], npix, rop)
+ call pl_update (pl, v, Mems[ll_out])
+ }
+
+ call sfree (sp)
+end
diff --git a/sys/plio/tf/plplrs.x b/sys/plio/tf/plplrs.x
new file mode 100644
index 00000000..13318070
--- /dev/null
+++ b/sys/plio/tf/plplrs.x
@@ -0,0 +1,41 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plio.h>
+
+# PL_PLR -- Put a line segment input as a range list to a mask, applying the
+# given ROP to combine the line segment with the existing line of the mask.
+
+procedure pl_plrs (pl, v, rl_src, rl_depth, npix, rop)
+
+pointer pl #I mask descriptor
+long v[PL_MAXDIM] #I vector coords of line segment
+short rl_src[ARB] #I input range list
+int rl_depth #I range list depth, bits
+int npix #I number of pixels to be set
+int rop #I rasterop
+
+int ll_len
+pointer sp, ll_src, ll_out, ll_dst
+pointer pl_access()
+int pl_r2ls()
+errchk pl_access
+
+begin
+ call smark (sp)
+ call salloc (ll_src, LL_MAXLEN(pl), TY_SHORT)
+
+ # Convert the range list to a line list.
+ ll_len = pl_r2ls (rl_src, 1, Mems[ll_src], npix)
+
+ if (!R_NEED_DST(rop) && v[1] == 1 && npix == PL_AXLEN(pl,1))
+ call pl_update (pl, v, Mems[ll_src])
+ else {
+ call salloc (ll_out, LL_MAXLEN(pl), TY_SHORT)
+ ll_dst = pl_access (pl,v)
+ call pl_linerop (Mems[ll_src], 1, PL_MAXVAL(pl), Mems[ll_dst], v[1],
+ MV(rl_depth), Mems[ll_out], npix, rop)
+ call pl_update (pl, v, Mems[ll_out])
+ }
+
+ call sfree (sp)
+end
diff --git a/sys/plio/tf/plpropi.x b/sys/plio/tf/plpropi.x
new file mode 100644
index 00000000..ecfe7227
--- /dev/null
+++ b/sys/plio/tf/plpropi.x
@@ -0,0 +1,177 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plset.h>
+include <plio.h>
+
+# PL_PIXROP -- Rasterop between source and destination pixel arrays.
+
+procedure pl_pixropi (px_src,xs,src_maxval, px_dst,ds,dst_maxval, npix, rop)
+
+int px_src[ARB] #I source pixel array
+int xs #I starting pixel index in src
+int src_maxval #I max pixel value in src mask
+int px_dst[ARB] #O destination pixel array
+int ds #I starting pixel index in dst
+int dst_maxval #I max pixel value in dst mask
+int npix #I number of pixels to convert
+int rop #I rasterop
+
+pointer sp, src
+int opcode, i
+int data, ceil, src_value
+int and(), or(), xor(), not()
+define out_ 91
+
+begin
+ opcode = R_OPCODE(rop)
+ data = R_DATA(rop)
+ ceil = 0
+
+ # Pixel value to be used if input mask is boolean.
+ if (src_maxval == 1) {
+ src_value = data
+ if (src_value <= 0)
+ src_value = dst_maxval
+ }
+
+ # Handle the easy cases first.
+ switch (opcode) {
+ case PIX_CLR:
+ call aclri (px_dst[ds], npix)
+ return
+ case PIX_SET:
+ call amovki (data, px_dst[ds], npix)
+ goto out_
+ case PIX_SRC:
+ if (src_maxval != 1)
+ call amovi (px_src[xs], px_dst[ds], npix)
+ else {
+ do i = 1, npix
+ if (px_src[xs+i-1] > 0)
+ px_dst[ds+i-1] = src_value
+ else
+ px_dst[ds+i-1] = 0
+ }
+
+ goto out_
+ case PIX_DST:
+ return # no-op
+ }
+
+ # Integer or boolean source mask?
+ if (src_maxval != 1) {
+ # Integer source mask; operate directly on source mask.
+
+ switch (opcode) {
+ case PIX_NOTSRC:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (px_src[xs+i-1])
+ case PIX_NOTDST:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (px_dst[xs+i-1])
+
+ case PIX_SRC_AND_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = and (px_src[xs+i-1], px_dst[ds+i-1])
+ case PIX_SRC_OR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = or (px_src[xs+i-1], px_dst[ds+i-1])
+ case PIX_SRC_XOR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = xor (px_src[xs+i-1], px_dst[ds+i-1])
+
+ case PIX_SRC_AND_NOTDST:
+ do i = 1, npix
+ px_dst[ds+i-1] = and (px_src[xs+i-1], not(px_dst[ds+i-1]))
+ case PIX_SRC_OR_NOTDST:
+ do i = 1, npix
+ px_dst[ds+i-1] = or (px_src[xs+i-1], not(px_dst[ds+i-1]))
+ case PIX_NOTSRC_AND_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = and (not(px_src[xs+i-1]), px_dst[ds+i-1])
+ case PIX_NOTSRC_OR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = or (not(px_src[xs+i-1]), px_dst[ds+i-1])
+
+ case PIX_NOT_SRC_AND_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (and (px_src[xs+i-1], px_dst[ds+i-1]))
+ case PIX_NOT_SRC_OR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = not ( or (px_src[xs+i-1], px_dst[ds+i-1]))
+ case PIX_NOT_SRC_XOR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (xor (px_src[xs+i-1], px_dst[ds+i-1]))
+ }
+
+ } else {
+ # Boolean source mask; use integer DATA value from ROP if source
+ # mask pixel is set.
+
+ call smark (sp)
+ call salloc (src, npix, TY_INT)
+
+ do i = 1, npix
+ if (px_src[xs+i-1] > 0)
+ Memi[src+i-1] = src_value
+ else
+ Memi[src+i-1] = 0
+
+ switch (opcode) {
+ case PIX_NOTSRC:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (Memi[src+i-1])
+ case PIX_NOTDST:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (px_dst[xs+i-1])
+
+ case PIX_SRC_AND_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = and (Memi[src+i-1], px_dst[ds+i-1])
+ case PIX_SRC_OR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = or (Memi[src+i-1], px_dst[ds+i-1])
+ case PIX_SRC_XOR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = xor (Memi[src+i-1], px_dst[ds+i-1])
+
+ case PIX_SRC_AND_NOTDST:
+ do i = 1, npix
+ px_dst[ds+i-1] = and (Memi[src+i-1], not(px_dst[ds+i-1]))
+ case PIX_SRC_OR_NOTDST:
+ do i = 1, npix
+ px_dst[ds+i-1] = or (Memi[src+i-1], not(px_dst[ds+i-1]))
+ case PIX_NOTSRC_AND_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = and (not(Memi[src+i-1]), px_dst[ds+i-1])
+ case PIX_NOTSRC_OR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = or (not(Memi[src+i-1]), px_dst[ds+i-1])
+
+ case PIX_NOT_SRC_AND_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (and (Memi[src+i-1], px_dst[ds+i-1]))
+ case PIX_NOT_SRC_OR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = not ( or (Memi[src+i-1], px_dst[ds+i-1]))
+ case PIX_NOT_SRC_XOR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (xor (Memi[src+i-1], px_dst[ds+i-1]))
+ }
+
+ call sfree (sp)
+ }
+out_
+ # If writing to an integer mask, mask the data to the indicated max
+ # value (necessary to avoid very large values if any NOT operations
+ # occurred). If writing to a boolean mask, map positive integer mask
+ # values to 1.
+
+ if (dst_maxval == 1) {
+ data = 1
+ call argti (px_dst[ds], npix, ceil, data)
+ } else if (dst_maxval > 1) {
+ data = dst_maxval
+ call aandki (px_dst[ds], data, px_dst[ds], npix)
+ }
+end
diff --git a/sys/plio/tf/plpropl.x b/sys/plio/tf/plpropl.x
new file mode 100644
index 00000000..1aa3b21c
--- /dev/null
+++ b/sys/plio/tf/plpropl.x
@@ -0,0 +1,177 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plset.h>
+include <plio.h>
+
+# PL_PIXROP -- Rasterop between source and destination pixel arrays.
+
+procedure pl_pixropl (px_src,xs,src_maxval, px_dst,ds,dst_maxval, npix, rop)
+
+long px_src[ARB] #I source pixel array
+int xs #I starting pixel index in src
+int src_maxval #I max pixel value in src mask
+long px_dst[ARB] #O destination pixel array
+int ds #I starting pixel index in dst
+int dst_maxval #I max pixel value in dst mask
+int npix #I number of pixels to convert
+int rop #I rasterop
+
+pointer sp, src
+int opcode, i
+long data, ceil, src_value
+int and(), or(), xor(), not()
+define out_ 91
+
+begin
+ opcode = R_OPCODE(rop)
+ data = R_DATA(rop)
+ ceil = 0
+
+ # Pixel value to be used if input mask is boolean.
+ if (src_maxval == 1) {
+ src_value = data
+ if (src_value <= 0)
+ src_value = dst_maxval
+ }
+
+ # Handle the easy cases first.
+ switch (opcode) {
+ case PIX_CLR:
+ call aclrl (px_dst[ds], npix)
+ return
+ case PIX_SET:
+ call amovkl (data, px_dst[ds], npix)
+ goto out_
+ case PIX_SRC:
+ if (src_maxval != 1)
+ call amovl (px_src[xs], px_dst[ds], npix)
+ else {
+ do i = 1, npix
+ if (px_src[xs+i-1] > 0)
+ px_dst[ds+i-1] = src_value
+ else
+ px_dst[ds+i-1] = 0
+ }
+
+ goto out_
+ case PIX_DST:
+ return # no-op
+ }
+
+ # Integer or boolean source mask?
+ if (src_maxval != 1) {
+ # Integer source mask; operate directly on source mask.
+
+ switch (opcode) {
+ case PIX_NOTSRC:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (px_src[xs+i-1])
+ case PIX_NOTDST:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (px_dst[xs+i-1])
+
+ case PIX_SRC_AND_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = and (px_src[xs+i-1], px_dst[ds+i-1])
+ case PIX_SRC_OR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = or (px_src[xs+i-1], px_dst[ds+i-1])
+ case PIX_SRC_XOR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = xor (px_src[xs+i-1], px_dst[ds+i-1])
+
+ case PIX_SRC_AND_NOTDST:
+ do i = 1, npix
+ px_dst[ds+i-1] = and (px_src[xs+i-1], not(px_dst[ds+i-1]))
+ case PIX_SRC_OR_NOTDST:
+ do i = 1, npix
+ px_dst[ds+i-1] = or (px_src[xs+i-1], not(px_dst[ds+i-1]))
+ case PIX_NOTSRC_AND_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = and (not(px_src[xs+i-1]), px_dst[ds+i-1])
+ case PIX_NOTSRC_OR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = or (not(px_src[xs+i-1]), px_dst[ds+i-1])
+
+ case PIX_NOT_SRC_AND_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (and (px_src[xs+i-1], px_dst[ds+i-1]))
+ case PIX_NOT_SRC_OR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = not ( or (px_src[xs+i-1], px_dst[ds+i-1]))
+ case PIX_NOT_SRC_XOR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (xor (px_src[xs+i-1], px_dst[ds+i-1]))
+ }
+
+ } else {
+ # Boolean source mask; use integer DATA value from ROP if source
+ # mask pixel is set.
+
+ call smark (sp)
+ call salloc (src, npix, TY_LONG)
+
+ do i = 1, npix
+ if (px_src[xs+i-1] > 0)
+ Meml[src+i-1] = src_value
+ else
+ Meml[src+i-1] = 0
+
+ switch (opcode) {
+ case PIX_NOTSRC:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (Meml[src+i-1])
+ case PIX_NOTDST:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (px_dst[xs+i-1])
+
+ case PIX_SRC_AND_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = and (Meml[src+i-1], px_dst[ds+i-1])
+ case PIX_SRC_OR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = or (Meml[src+i-1], px_dst[ds+i-1])
+ case PIX_SRC_XOR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = xor (Meml[src+i-1], px_dst[ds+i-1])
+
+ case PIX_SRC_AND_NOTDST:
+ do i = 1, npix
+ px_dst[ds+i-1] = and (Meml[src+i-1], not(px_dst[ds+i-1]))
+ case PIX_SRC_OR_NOTDST:
+ do i = 1, npix
+ px_dst[ds+i-1] = or (Meml[src+i-1], not(px_dst[ds+i-1]))
+ case PIX_NOTSRC_AND_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = and (not(Meml[src+i-1]), px_dst[ds+i-1])
+ case PIX_NOTSRC_OR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = or (not(Meml[src+i-1]), px_dst[ds+i-1])
+
+ case PIX_NOT_SRC_AND_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (and (Meml[src+i-1], px_dst[ds+i-1]))
+ case PIX_NOT_SRC_OR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = not ( or (Meml[src+i-1], px_dst[ds+i-1]))
+ case PIX_NOT_SRC_XOR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (xor (Meml[src+i-1], px_dst[ds+i-1]))
+ }
+
+ call sfree (sp)
+ }
+out_
+ # If writing to an integer mask, mask the data to the indicated max
+ # value (necessary to avoid very large values if any NOT operations
+ # occurred). If writing to a boolean mask, map positive integer mask
+ # values to 1.
+
+ if (dst_maxval == 1) {
+ data = 1
+ call argtl (px_dst[ds], npix, ceil, data)
+ } else if (dst_maxval > 1) {
+ data = dst_maxval
+ call aandkl (px_dst[ds], data, px_dst[ds], npix)
+ }
+end
diff --git a/sys/plio/tf/plprops.x b/sys/plio/tf/plprops.x
new file mode 100644
index 00000000..f06baadb
--- /dev/null
+++ b/sys/plio/tf/plprops.x
@@ -0,0 +1,177 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plset.h>
+include <plio.h>
+
+# PL_PIXROP -- Rasterop between source and destination pixel arrays.
+
+procedure pl_pixrops (px_src,xs,src_maxval, px_dst,ds,dst_maxval, npix, rop)
+
+short px_src[ARB] #I source pixel array
+int xs #I starting pixel index in src
+int src_maxval #I max pixel value in src mask
+short px_dst[ARB] #O destination pixel array
+int ds #I starting pixel index in dst
+int dst_maxval #I max pixel value in dst mask
+int npix #I number of pixels to convert
+int rop #I rasterop
+
+pointer sp, src
+int opcode, i
+short data, ceil, src_value
+int and(), or(), xor(), not()
+define out_ 91
+
+begin
+ opcode = R_OPCODE(rop)
+ data = R_DATA(rop)
+ ceil = 0
+
+ # Pixel value to be used if input mask is boolean.
+ if (src_maxval == 1) {
+ src_value = data
+ if (src_value <= 0)
+ src_value = dst_maxval
+ }
+
+ # Handle the easy cases first.
+ switch (opcode) {
+ case PIX_CLR:
+ call aclrs (px_dst[ds], npix)
+ return
+ case PIX_SET:
+ call amovks (data, px_dst[ds], npix)
+ goto out_
+ case PIX_SRC:
+ if (src_maxval != 1)
+ call amovs (px_src[xs], px_dst[ds], npix)
+ else {
+ do i = 1, npix
+ if (px_src[xs+i-1] > 0)
+ px_dst[ds+i-1] = src_value
+ else
+ px_dst[ds+i-1] = 0
+ }
+
+ goto out_
+ case PIX_DST:
+ return # no-op
+ }
+
+ # Integer or boolean source mask?
+ if (src_maxval != 1) {
+ # Integer source mask; operate directly on source mask.
+
+ switch (opcode) {
+ case PIX_NOTSRC:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (px_src[xs+i-1])
+ case PIX_NOTDST:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (px_dst[xs+i-1])
+
+ case PIX_SRC_AND_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = and (px_src[xs+i-1], px_dst[ds+i-1])
+ case PIX_SRC_OR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = or (px_src[xs+i-1], px_dst[ds+i-1])
+ case PIX_SRC_XOR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = xor (px_src[xs+i-1], px_dst[ds+i-1])
+
+ case PIX_SRC_AND_NOTDST:
+ do i = 1, npix
+ px_dst[ds+i-1] = and (px_src[xs+i-1], not(px_dst[ds+i-1]))
+ case PIX_SRC_OR_NOTDST:
+ do i = 1, npix
+ px_dst[ds+i-1] = or (px_src[xs+i-1], not(px_dst[ds+i-1]))
+ case PIX_NOTSRC_AND_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = and (not(px_src[xs+i-1]), px_dst[ds+i-1])
+ case PIX_NOTSRC_OR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = or (not(px_src[xs+i-1]), px_dst[ds+i-1])
+
+ case PIX_NOT_SRC_AND_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (and (px_src[xs+i-1], px_dst[ds+i-1]))
+ case PIX_NOT_SRC_OR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = not ( or (px_src[xs+i-1], px_dst[ds+i-1]))
+ case PIX_NOT_SRC_XOR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (xor (px_src[xs+i-1], px_dst[ds+i-1]))
+ }
+
+ } else {
+ # Boolean source mask; use integer DATA value from ROP if source
+ # mask pixel is set.
+
+ call smark (sp)
+ call salloc (src, npix, TY_SHORT)
+
+ do i = 1, npix
+ if (px_src[xs+i-1] > 0)
+ Mems[src+i-1] = src_value
+ else
+ Mems[src+i-1] = 0
+
+ switch (opcode) {
+ case PIX_NOTSRC:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (Mems[src+i-1])
+ case PIX_NOTDST:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (px_dst[xs+i-1])
+
+ case PIX_SRC_AND_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = and (Mems[src+i-1], px_dst[ds+i-1])
+ case PIX_SRC_OR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = or (Mems[src+i-1], px_dst[ds+i-1])
+ case PIX_SRC_XOR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = xor (Mems[src+i-1], px_dst[ds+i-1])
+
+ case PIX_SRC_AND_NOTDST:
+ do i = 1, npix
+ px_dst[ds+i-1] = and (Mems[src+i-1], not(px_dst[ds+i-1]))
+ case PIX_SRC_OR_NOTDST:
+ do i = 1, npix
+ px_dst[ds+i-1] = or (Mems[src+i-1], not(px_dst[ds+i-1]))
+ case PIX_NOTSRC_AND_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = and (not(Mems[src+i-1]), px_dst[ds+i-1])
+ case PIX_NOTSRC_OR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = or (not(Mems[src+i-1]), px_dst[ds+i-1])
+
+ case PIX_NOT_SRC_AND_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (and (Mems[src+i-1], px_dst[ds+i-1]))
+ case PIX_NOT_SRC_OR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = not ( or (Mems[src+i-1], px_dst[ds+i-1]))
+ case PIX_NOT_SRC_XOR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (xor (Mems[src+i-1], px_dst[ds+i-1]))
+ }
+
+ call sfree (sp)
+ }
+out_
+ # If writing to an integer mask, mask the data to the indicated max
+ # value (necessary to avoid very large values if any NOT operations
+ # occurred). If writing to a boolean mask, map positive integer mask
+ # values to 1.
+
+ if (dst_maxval == 1) {
+ data = 1
+ call argts (px_dst[ds], npix, ceil, data)
+ } else if (dst_maxval > 1) {
+ data = dst_maxval
+ call aandks (px_dst[ds], data, px_dst[ds], npix)
+ }
+end
diff --git a/sys/plio/tf/plr2li.x b/sys/plio/tf/plr2li.x
new file mode 100644
index 00000000..f6fb6c79
--- /dev/null
+++ b/sys/plio/tf/plr2li.x
@@ -0,0 +1,130 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plset.h>
+include <plio.h>
+
+# PL_R2L -- Convert a range list to a line list. The length of the output
+# line list is returned as the function value.
+
+int procedure pl_r2li (rl_src, xs, ll_dst, npix)
+
+int rl_src[3,ARB] #I input range list
+int xs #I starting pixel index in range list
+short ll_dst[ARB] #O destination line list
+int npix #I number of pixels to convert
+
+int hi, pv
+int last, xe, x1, x2, iz, op, np, nz, nr, dv, v, i
+define done_ 91
+
+begin
+ # No input pixels?
+ nr = RL_LEN(rl_src)
+ if (npix <= 0 || nr <= 0)
+ return (0)
+
+ # Initialize the linelist header.
+ LL_VERSION(ll_dst) = LL_CURVERSION
+ LL_HDRLEN(ll_dst) = LL_CURHDRLEN
+ LL_NREFS(ll_dst) = 0
+ LL_SETBLEN(ll_dst,0)
+
+ xe = xs + npix - 1
+ op = LL_CURHDRLEN + 1
+ iz = xs
+ hi = 1
+
+ # Process the array of range lists.
+ do i = RL_FIRST, nr + 1 {
+ if (i <= nr) {
+ # Load next range.
+ x1 = rl_src[1,i]
+ np = rl_src[2,i]
+ pv = rl_src[3,i]
+ x2 = x1 + np - 1
+ last = x2
+
+ # Get an inbounds range.
+ if (x1 > xe)
+ break
+ else if (xs > x2)
+ next
+ else if (x1 < xs)
+ x1 = xs
+ else if (x2 > xe)
+ x2 = xe
+
+ # Go again if nothing inbounds.
+ nz = x1 - iz
+ np = x2 - x1 + 1
+ if (np <= 0)
+ next
+
+ } else if (iz < xe) {
+ # At end of input range list, but need to output a ZN.
+ nz = xe - iz + 1
+ np = 0
+ pv = 0
+ } else
+ break
+
+ # Encode an instruction to regenerate the current range I0-IP
+ # of N data values of nonzero level PV. In the most complex case
+ # we must update the high value and output a range of zeros,
+ # followed by a range of NP high values. If NP is 1, we can
+ # probably use a PN or [ID]S instruction to save space.
+
+ # Change the high value?
+ if (pv > 0) {
+ dv = pv - hi
+ if (dv != 0) {
+ # Output IH or DH instruction?
+ hi = pv
+ if (abs(dv) > I_DATAMAX) {
+ ll_dst[op] = M_SH + and (int(pv), I_DATAMAX)
+ op = op + 1
+ ll_dst[op] = pv / I_SHIFT
+ op = op + 1
+ } else {
+ if (dv < 0)
+ ll_dst[op] = M_DH + (-dv)
+ else
+ ll_dst[op] = M_IH + dv
+ op = op + 1
+
+ # Convert to IS or DS if range is a single pixel.
+ if (np == 1 && nz == 0) {
+ v = ll_dst[op-1]
+ ll_dst[op-1] = or (v, M_MOVE)
+ goto done_
+ }
+ }
+ }
+ }
+
+ # Output range of zeros to catch up to current range?
+ if (nz > 0) {
+ # Output the ZN instruction.
+ for (; nz > 0; nz = nz - (I_DATAMAX-1)) {
+ ll_dst[op] = M_ZN + min(I_DATAMAX-1,nz)
+ op = op + 1
+ }
+ # Convert to PN if range is a single pixel.
+ if (np == 1 && pv > 0 && x2 == last) {
+ ll_dst[op-1] = ll_dst[op-1] + M_PN + 1
+ goto done_
+ }
+ }
+
+ # The only thing left is the HN instruction if we get here.
+ for (; np > 0; np = np - I_DATAMAX) {
+ ll_dst[op] = M_HN + min(I_DATAMAX,np)
+ op = op + 1
+ }
+done_
+ iz = x2 + 1
+ }
+
+ LL_SETLEN(ll_dst, op - 1)
+ return (op - 1)
+end
diff --git a/sys/plio/tf/plr2ll.x b/sys/plio/tf/plr2ll.x
new file mode 100644
index 00000000..b21d6678
--- /dev/null
+++ b/sys/plio/tf/plr2ll.x
@@ -0,0 +1,130 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plset.h>
+include <plio.h>
+
+# PL_R2L -- Convert a range list to a line list. The length of the output
+# line list is returned as the function value.
+
+int procedure pl_r2ll (rl_src, xs, ll_dst, npix)
+
+long rl_src[3,ARB] #I input range list
+int xs #I starting pixel index in range list
+short ll_dst[ARB] #O destination line list
+int npix #I number of pixels to convert
+
+long hi, pv
+int last, xe, x1, x2, iz, op, np, nz, nr, dv, v, i
+define done_ 91
+
+begin
+ # No input pixels?
+ nr = RL_LEN(rl_src)
+ if (npix <= 0 || nr <= 0)
+ return (0)
+
+ # Initialize the linelist header.
+ LL_VERSION(ll_dst) = LL_CURVERSION
+ LL_HDRLEN(ll_dst) = LL_CURHDRLEN
+ LL_NREFS(ll_dst) = 0
+ LL_SETBLEN(ll_dst,0)
+
+ xe = xs + npix - 1
+ op = LL_CURHDRLEN + 1
+ iz = xs
+ hi = 1
+
+ # Process the array of range lists.
+ do i = RL_FIRST, nr + 1 {
+ if (i <= nr) {
+ # Load next range.
+ x1 = rl_src[1,i]
+ np = rl_src[2,i]
+ pv = rl_src[3,i]
+ x2 = x1 + np - 1
+ last = x2
+
+ # Get an inbounds range.
+ if (x1 > xe)
+ break
+ else if (xs > x2)
+ next
+ else if (x1 < xs)
+ x1 = xs
+ else if (x2 > xe)
+ x2 = xe
+
+ # Go again if nothing inbounds.
+ nz = x1 - iz
+ np = x2 - x1 + 1
+ if (np <= 0)
+ next
+
+ } else if (iz < xe) {
+ # At end of input range list, but need to output a ZN.
+ nz = xe - iz + 1
+ np = 0
+ pv = 0
+ } else
+ break
+
+ # Encode an instruction to regenerate the current range I0-IP
+ # of N data values of nonzero level PV. In the most complex case
+ # we must update the high value and output a range of zeros,
+ # followed by a range of NP high values. If NP is 1, we can
+ # probably use a PN or [ID]S instruction to save space.
+
+ # Change the high value?
+ if (pv > 0) {
+ dv = pv - hi
+ if (dv != 0) {
+ # Output IH or DH instruction?
+ hi = pv
+ if (abs(dv) > I_DATAMAX) {
+ ll_dst[op] = M_SH + and (int(pv), I_DATAMAX)
+ op = op + 1
+ ll_dst[op] = pv / I_SHIFT
+ op = op + 1
+ } else {
+ if (dv < 0)
+ ll_dst[op] = M_DH + (-dv)
+ else
+ ll_dst[op] = M_IH + dv
+ op = op + 1
+
+ # Convert to IS or DS if range is a single pixel.
+ if (np == 1 && nz == 0) {
+ v = ll_dst[op-1]
+ ll_dst[op-1] = or (v, M_MOVE)
+ goto done_
+ }
+ }
+ }
+ }
+
+ # Output range of zeros to catch up to current range?
+ if (nz > 0) {
+ # Output the ZN instruction.
+ for (; nz > 0; nz = nz - (I_DATAMAX-1)) {
+ ll_dst[op] = M_ZN + min(I_DATAMAX-1,nz)
+ op = op + 1
+ }
+ # Convert to PN if range is a single pixel.
+ if (np == 1 && pv > 0 && x2 == last) {
+ ll_dst[op-1] = ll_dst[op-1] + M_PN + 1
+ goto done_
+ }
+ }
+
+ # The only thing left is the HN instruction if we get here.
+ for (; np > 0; np = np - I_DATAMAX) {
+ ll_dst[op] = M_HN + min(I_DATAMAX,np)
+ op = op + 1
+ }
+done_
+ iz = x2 + 1
+ }
+
+ LL_SETLEN(ll_dst, op - 1)
+ return (op - 1)
+end
diff --git a/sys/plio/tf/plr2ls.x b/sys/plio/tf/plr2ls.x
new file mode 100644
index 00000000..6aceca17
--- /dev/null
+++ b/sys/plio/tf/plr2ls.x
@@ -0,0 +1,130 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plset.h>
+include <plio.h>
+
+# PL_R2L -- Convert a range list to a line list. The length of the output
+# line list is returned as the function value.
+
+int procedure pl_r2ls (rl_src, xs, ll_dst, npix)
+
+short rl_src[3,ARB] #I input range list
+int xs #I starting pixel index in range list
+short ll_dst[ARB] #O destination line list
+int npix #I number of pixels to convert
+
+short hi, pv
+int last, xe, x1, x2, iz, op, np, nz, nr, dv, v, i
+define done_ 91
+
+begin
+ # No input pixels?
+ nr = RL_LEN(rl_src)
+ if (npix <= 0 || nr <= 0)
+ return (0)
+
+ # Initialize the linelist header.
+ LL_VERSION(ll_dst) = LL_CURVERSION
+ LL_HDRLEN(ll_dst) = LL_CURHDRLEN
+ LL_NREFS(ll_dst) = 0
+ LL_SETBLEN(ll_dst,0)
+
+ xe = xs + npix - 1
+ op = LL_CURHDRLEN + 1
+ iz = xs
+ hi = 1
+
+ # Process the array of range lists.
+ do i = RL_FIRST, nr + 1 {
+ if (i <= nr) {
+ # Load next range.
+ x1 = rl_src[1,i]
+ np = rl_src[2,i]
+ pv = rl_src[3,i]
+ x2 = x1 + np - 1
+ last = x2
+
+ # Get an inbounds range.
+ if (x1 > xe)
+ break
+ else if (xs > x2)
+ next
+ else if (x1 < xs)
+ x1 = xs
+ else if (x2 > xe)
+ x2 = xe
+
+ # Go again if nothing inbounds.
+ nz = x1 - iz
+ np = x2 - x1 + 1
+ if (np <= 0)
+ next
+
+ } else if (iz < xe) {
+ # At end of input range list, but need to output a ZN.
+ nz = xe - iz + 1
+ np = 0
+ pv = 0
+ } else
+ break
+
+ # Encode an instruction to regenerate the current range I0-IP
+ # of N data values of nonzero level PV. In the most complex case
+ # we must update the high value and output a range of zeros,
+ # followed by a range of NP high values. If NP is 1, we can
+ # probably use a PN or [ID]S instruction to save space.
+
+ # Change the high value?
+ if (pv > 0) {
+ dv = pv - hi
+ if (dv != 0) {
+ # Output IH or DH instruction?
+ hi = pv
+ if (abs(dv) > I_DATAMAX) {
+ ll_dst[op] = M_SH + and (int(pv), I_DATAMAX)
+ op = op + 1
+ ll_dst[op] = pv / I_SHIFT
+ op = op + 1
+ } else {
+ if (dv < 0)
+ ll_dst[op] = M_DH + (-dv)
+ else
+ ll_dst[op] = M_IH + dv
+ op = op + 1
+
+ # Convert to IS or DS if range is a single pixel.
+ if (np == 1 && nz == 0) {
+ v = ll_dst[op-1]
+ ll_dst[op-1] = or (v, M_MOVE)
+ goto done_
+ }
+ }
+ }
+ }
+
+ # Output range of zeros to catch up to current range?
+ if (nz > 0) {
+ # Output the ZN instruction.
+ for (; nz > 0; nz = nz - (I_DATAMAX-1)) {
+ ll_dst[op] = M_ZN + min(I_DATAMAX-1,nz)
+ op = op + 1
+ }
+ # Convert to PN if range is a single pixel.
+ if (np == 1 && pv > 0 && x2 == last) {
+ ll_dst[op-1] = ll_dst[op-1] + M_PN + 1
+ goto done_
+ }
+ }
+
+ # The only thing left is the HN instruction if we get here.
+ for (; np > 0; np = np - I_DATAMAX) {
+ ll_dst[op] = M_HN + min(I_DATAMAX,np)
+ op = op + 1
+ }
+done_
+ iz = x2 + 1
+ }
+
+ LL_SETLEN(ll_dst, op - 1)
+ return (op - 1)
+end
diff --git a/sys/plio/tf/plr2pi.x b/sys/plio/tf/plr2pi.x
new file mode 100644
index 00000000..57db5b63
--- /dev/null
+++ b/sys/plio/tf/plr2pi.x
@@ -0,0 +1,74 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plset.h>
+include <plio.h>
+
+# PL_R2P -- Convert a range list to a pixel array. The number of pixels
+# output (always npix) is returned as the function value.
+
+int procedure pl_r2pi (rl_src, xs, px_dst, npix)
+
+int rl_src[3,ARB] #I input range list
+int xs #I starting pixel index in range list
+int px_dst[ARB] #O output pixel array
+int npix #I number of pixels to convert
+
+int hi, pv
+int xe, x1, x2, iz, op, np, nz, nr, i, j
+define done_ 91
+
+begin
+ # No input pixels?
+ nr = RL_LEN(rl_src)
+ if (npix <= 0 || nr <= 0)
+ return (0)
+
+ xe = xs + npix - 1
+ iz = xs
+ op = 1
+ hi = 1
+
+ # Process the array of range lists.
+ do i = RL_FIRST, nr {
+ x1 = rl_src[1,i]
+ np = rl_src[2,i]
+ pv = rl_src[3,i]
+ x2 = x1 + np - 1
+
+ # Get an inbounds range.
+ if (x1 > xe)
+ break
+ else if (xs > x2)
+ next
+ else if (x1 < xs)
+ x1 = xs
+ else if (x2 > xe)
+ x2 = xe
+
+ nz = x1 - iz
+ np = x2 - x1 + 1
+ if (np <= 0)
+ next
+
+ # Output range of zeros to catch up to current range?
+ if (nz > 0) {
+ do j = 1, nz
+ px_dst[op+j-1] = 0
+ op = op + nz
+ }
+
+ # Output the pixels.
+ do j = 1, np
+ px_dst[op+j-1] = pv
+ op = op + np
+done_
+ x1 = x2 + 1
+ iz = x1
+ }
+
+ # Zero any remaining output range.
+ do i = op, npix
+ px_dst[i] = 0
+
+ return (npix)
+end
diff --git a/sys/plio/tf/plr2pl.x b/sys/plio/tf/plr2pl.x
new file mode 100644
index 00000000..763bb8d2
--- /dev/null
+++ b/sys/plio/tf/plr2pl.x
@@ -0,0 +1,74 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plset.h>
+include <plio.h>
+
+# PL_R2P -- Convert a range list to a pixel array. The number of pixels
+# output (always npix) is returned as the function value.
+
+int procedure pl_r2pl (rl_src, xs, px_dst, npix)
+
+long rl_src[3,ARB] #I input range list
+int xs #I starting pixel index in range list
+long px_dst[ARB] #O output pixel array
+int npix #I number of pixels to convert
+
+long hi, pv
+int xe, x1, x2, iz, op, np, nz, nr, i, j
+define done_ 91
+
+begin
+ # No input pixels?
+ nr = RL_LEN(rl_src)
+ if (npix <= 0 || nr <= 0)
+ return (0)
+
+ xe = xs + npix - 1
+ iz = xs
+ op = 1
+ hi = 1
+
+ # Process the array of range lists.
+ do i = RL_FIRST, nr {
+ x1 = rl_src[1,i]
+ np = rl_src[2,i]
+ pv = rl_src[3,i]
+ x2 = x1 + np - 1
+
+ # Get an inbounds range.
+ if (x1 > xe)
+ break
+ else if (xs > x2)
+ next
+ else if (x1 < xs)
+ x1 = xs
+ else if (x2 > xe)
+ x2 = xe
+
+ nz = x1 - iz
+ np = x2 - x1 + 1
+ if (np <= 0)
+ next
+
+ # Output range of zeros to catch up to current range?
+ if (nz > 0) {
+ do j = 1, nz
+ px_dst[op+j-1] = 0
+ op = op + nz
+ }
+
+ # Output the pixels.
+ do j = 1, np
+ px_dst[op+j-1] = pv
+ op = op + np
+done_
+ x1 = x2 + 1
+ iz = x1
+ }
+
+ # Zero any remaining output range.
+ do i = op, npix
+ px_dst[i] = 0
+
+ return (npix)
+end
diff --git a/sys/plio/tf/plr2ps.x b/sys/plio/tf/plr2ps.x
new file mode 100644
index 00000000..ecba387d
--- /dev/null
+++ b/sys/plio/tf/plr2ps.x
@@ -0,0 +1,74 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plset.h>
+include <plio.h>
+
+# PL_R2P -- Convert a range list to a pixel array. The number of pixels
+# output (always npix) is returned as the function value.
+
+int procedure pl_r2ps (rl_src, xs, px_dst, npix)
+
+short rl_src[3,ARB] #I input range list
+int xs #I starting pixel index in range list
+short px_dst[ARB] #O output pixel array
+int npix #I number of pixels to convert
+
+short hi, pv
+int xe, x1, x2, iz, op, np, nz, nr, i, j
+define done_ 91
+
+begin
+ # No input pixels?
+ nr = RL_LEN(rl_src)
+ if (npix <= 0 || nr <= 0)
+ return (0)
+
+ xe = xs + npix - 1
+ iz = xs
+ op = 1
+ hi = 1
+
+ # Process the array of range lists.
+ do i = RL_FIRST, nr {
+ x1 = rl_src[1,i]
+ np = rl_src[2,i]
+ pv = rl_src[3,i]
+ x2 = x1 + np - 1
+
+ # Get an inbounds range.
+ if (x1 > xe)
+ break
+ else if (xs > x2)
+ next
+ else if (x1 < xs)
+ x1 = xs
+ else if (x2 > xe)
+ x2 = xe
+
+ nz = x1 - iz
+ np = x2 - x1 + 1
+ if (np <= 0)
+ next
+
+ # Output range of zeros to catch up to current range?
+ if (nz > 0) {
+ do j = 1, nz
+ px_dst[op+j-1] = 0
+ op = op + nz
+ }
+
+ # Output the pixels.
+ do j = 1, np
+ px_dst[op+j-1] = pv
+ op = op + np
+done_
+ x1 = x2 + 1
+ iz = x1
+ }
+
+ # Zero any remaining output range.
+ do i = op, npix
+ px_dst[i] = 0
+
+ return (npix)
+end
diff --git a/sys/plio/tf/plreqi.x b/sys/plio/tf/plreqi.x
new file mode 100644
index 00000000..0307efea
--- /dev/null
+++ b/sys/plio/tf/plreqi.x
@@ -0,0 +1,27 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plset.h>
+
+# PLR_EQUAL -- Compare two range lists for equality.
+
+bool procedure plr_equali (r1, r2)
+
+int r1[3,ARB] #I range list 1
+int r2[3,ARB] #I range list 2
+
+int i
+int len1, len2
+
+begin
+ len1 = RL_LEN(r1)
+ len2 = RL_LEN(r2)
+
+ if (len1 != len2)
+ return (false)
+
+ do i = RL_FIRST, len1
+ if (r1[1,i] != r2[1,i] || r1[2,i] != r2[2,i] || r1[3,i] != r2[3,i])
+ return (false)
+
+ return (true)
+end
diff --git a/sys/plio/tf/plreql.x b/sys/plio/tf/plreql.x
new file mode 100644
index 00000000..1fb76d6a
--- /dev/null
+++ b/sys/plio/tf/plreql.x
@@ -0,0 +1,27 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plset.h>
+
+# PLR_EQUAL -- Compare two range lists for equality.
+
+bool procedure plr_equall (r1, r2)
+
+long r1[3,ARB] #I range list 1
+long r2[3,ARB] #I range list 2
+
+int i
+int len1, len2
+
+begin
+ len1 = RL_LEN(r1)
+ len2 = RL_LEN(r2)
+
+ if (len1 != len2)
+ return (false)
+
+ do i = RL_FIRST, len1
+ if (r1[1,i] != r2[1,i] || r1[2,i] != r2[2,i] || r1[3,i] != r2[3,i])
+ return (false)
+
+ return (true)
+end
diff --git a/sys/plio/tf/plreqs.x b/sys/plio/tf/plreqs.x
new file mode 100644
index 00000000..b44bf4da
--- /dev/null
+++ b/sys/plio/tf/plreqs.x
@@ -0,0 +1,27 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plset.h>
+
+# PLR_EQUAL -- Compare two range lists for equality.
+
+bool procedure plr_equals (r1, r2)
+
+short r1[3,ARB] #I range list 1
+short r2[3,ARB] #I range list 2
+
+int i
+int len1, len2
+
+begin
+ len1 = RL_LEN(r1)
+ len2 = RL_LEN(r2)
+
+ if (len1 != len2)
+ return (false)
+
+ do i = RL_FIRST, len1
+ if (r1[1,i] != r2[1,i] || r1[2,i] != r2[2,i] || r1[3,i] != r2[3,i])
+ return (false)
+
+ return (true)
+end
diff --git a/sys/plio/tf/plrpri.x b/sys/plio/tf/plrpri.x
new file mode 100644
index 00000000..a74e7791
--- /dev/null
+++ b/sys/plio/tf/plrpri.x
@@ -0,0 +1,56 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plset.h>
+include <plio.h>
+
+# PLR_PRINT -- Print a range list on the given output stream.
+
+procedure plr_printi (rl, fd, label, firstcol, maxcol)
+
+int rl[3,ARB] #I range list
+int fd #I output file
+char label[ARB] #I line label
+int firstcol #I first column for output
+int maxcol #I width of formatted output
+
+pointer sp, buf
+int col, rn, r_len, x, n, pv
+int strlen()
+
+begin
+ call smark (sp)
+ call salloc (buf, SZ_LINE, TY_CHAR)
+
+ # Output the line label and advance to the first column. If the label
+ # extends beyond the first column, start a new line.
+
+ call putline (fd, label)
+ col = strlen (label) + 1
+ if (col > firstcol)
+ call pl_debugout (fd, "", col, firstcol, maxcol)
+
+ r_len = RL_LEN(rl)
+
+ # Decode the range list proper.
+ do rn = RL_FIRST, r_len {
+ x = RL_X(rl,rn)
+ n = RL_N(rl,rn)
+ pv = RL_V(rl,rn)
+
+ if (n == 1) {
+ call sprintf (Memc[buf], SZ_LINE, "%d(%d)")
+ call pargi (x)
+ call pargi (pv)
+ } else {
+ call sprintf (Memc[buf], SZ_LINE, "%d-%d(%d)")
+ call pargi (x)
+ call pargi (x+n-1)
+ call pargi (pv)
+ }
+
+ call pl_debugout (fd, Memc[buf], col, firstcol, maxcol)
+ }
+
+ call pl_debugout (fd, "", col, firstcol, maxcol)
+ call sfree (sp)
+end
diff --git a/sys/plio/tf/plrprl.x b/sys/plio/tf/plrprl.x
new file mode 100644
index 00000000..6357cd71
--- /dev/null
+++ b/sys/plio/tf/plrprl.x
@@ -0,0 +1,56 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plset.h>
+include <plio.h>
+
+# PLR_PRINT -- Print a range list on the given output stream.
+
+procedure plr_printl (rl, fd, label, firstcol, maxcol)
+
+long rl[3,ARB] #I range list
+int fd #I output file
+char label[ARB] #I line label
+int firstcol #I first column for output
+int maxcol #I width of formatted output
+
+pointer sp, buf
+int col, rn, r_len, x, n, pv
+int strlen()
+
+begin
+ call smark (sp)
+ call salloc (buf, SZ_LINE, TY_CHAR)
+
+ # Output the line label and advance to the first column. If the label
+ # extends beyond the first column, start a new line.
+
+ call putline (fd, label)
+ col = strlen (label) + 1
+ if (col > firstcol)
+ call pl_debugout (fd, "", col, firstcol, maxcol)
+
+ r_len = RL_LEN(rl)
+
+ # Decode the range list proper.
+ do rn = RL_FIRST, r_len {
+ x = RL_X(rl,rn)
+ n = RL_N(rl,rn)
+ pv = RL_V(rl,rn)
+
+ if (n == 1) {
+ call sprintf (Memc[buf], SZ_LINE, "%d(%d)")
+ call pargi (x)
+ call pargi (pv)
+ } else {
+ call sprintf (Memc[buf], SZ_LINE, "%d-%d(%d)")
+ call pargi (x)
+ call pargi (x+n-1)
+ call pargi (pv)
+ }
+
+ call pl_debugout (fd, Memc[buf], col, firstcol, maxcol)
+ }
+
+ call pl_debugout (fd, "", col, firstcol, maxcol)
+ call sfree (sp)
+end
diff --git a/sys/plio/tf/plrprs.x b/sys/plio/tf/plrprs.x
new file mode 100644
index 00000000..e055f851
--- /dev/null
+++ b/sys/plio/tf/plrprs.x
@@ -0,0 +1,56 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plset.h>
+include <plio.h>
+
+# PLR_PRINT -- Print a range list on the given output stream.
+
+procedure plr_prints (rl, fd, label, firstcol, maxcol)
+
+short rl[3,ARB] #I range list
+int fd #I output file
+char label[ARB] #I line label
+int firstcol #I first column for output
+int maxcol #I width of formatted output
+
+pointer sp, buf
+int col, rn, r_len, x, n, pv
+int strlen()
+
+begin
+ call smark (sp)
+ call salloc (buf, SZ_LINE, TY_CHAR)
+
+ # Output the line label and advance to the first column. If the label
+ # extends beyond the first column, start a new line.
+
+ call putline (fd, label)
+ col = strlen (label) + 1
+ if (col > firstcol)
+ call pl_debugout (fd, "", col, firstcol, maxcol)
+
+ r_len = RL_LEN(rl)
+
+ # Decode the range list proper.
+ do rn = RL_FIRST, r_len {
+ x = RL_X(rl,rn)
+ n = RL_N(rl,rn)
+ pv = RL_V(rl,rn)
+
+ if (n == 1) {
+ call sprintf (Memc[buf], SZ_LINE, "%d(%d)")
+ call pargi (x)
+ call pargi (pv)
+ } else {
+ call sprintf (Memc[buf], SZ_LINE, "%d-%d(%d)")
+ call pargi (x)
+ call pargi (x+n-1)
+ call pargi (pv)
+ }
+
+ call pl_debugout (fd, Memc[buf], col, firstcol, maxcol)
+ }
+
+ call pl_debugout (fd, "", col, firstcol, maxcol)
+ call sfree (sp)
+end
diff --git a/sys/plio/tf/plrropi.x b/sys/plio/tf/plrropi.x
new file mode 100644
index 00000000..72292323
--- /dev/null
+++ b/sys/plio/tf/plrropi.x
@@ -0,0 +1,195 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plset.h>
+include <plio.h>
+include "../plrseg.h"
+
+# PL_RANGEROP -- Rasterop operation between source and destination range lists.
+# The indicated rasterop operation is performed upon the source and destination
+# range lists, writing the result to RL_OUT, which is a copy of RL_DST except
+# for the region affected by the rasterop operation (note that the destination
+# range list cannot be edited in place since it may change size).
+
+procedure pl_rangeropi (rl_src, xs, src_maxval,
+ rl_dst, ds, dst_maxval, rl_out, npix, rop)
+
+int rl_src[3,ARB] #I source range list
+int xs #I starting pixel index in src range list
+int src_maxval #I max pixel value in src mask
+int rl_dst[3,ARB] #I destination range list
+int ds #I starting pixel index in dst range list
+int dst_maxval #I max pixel value in dst mask
+int rl_out[3,ARB] #O output list (edited version of rl_dst)
+int npix #I number of pixels to convert
+int rop #I rasterop
+
+bool need_src, need_dst, rop_enable
+int data, src_value, v_src, v_dst, pv
+int segsize, opcode, x, i, np, rn_o, p
+int d_src[LEN_PLRDES], d_dst[LEN_PLRDES]
+
+begin
+ need_src = R_NEED_SRC(rop)
+ need_dst = R_NEED_DST(rop)
+ opcode = R_OPCODE(rop)
+ data = R_DATA(rop)
+
+ # Pixel value to be used if input mask is boolean.
+ if (src_maxval == 1) {
+ src_value = data
+ if (src_value <= 0)
+ src_value = dst_maxval
+ }
+
+ # Advance to the desired position in the source list, discarding
+ # the unused ranges. The point XS may lie within a range or in a
+ # zero area of the input line.
+
+ if (need_src) {
+ x = 1
+ plr_init (rl_src, d_src)
+ do i = 1, ARB {
+ np = min (plr_nleft(d_src), xs - x)
+ plr_getseg (rl_src, d_src, np, v_src)
+ x = x + np
+ if (x >= xs || np == 0)
+ break
+ }
+ }
+
+ # Advance through both the source and destination lists, extracting
+ # line segments which have a constant value in each input list; the
+ # values for the two lists may differ. Apply the given rasterop to
+ # the source and destination pixel values and write each line segment
+ # as a range to the output list. If the ranges in the two input lists
+ # differ (randomly overlap) then the output list will generally be
+ # more fragmented, i.e., have more ranges of constant value. As each
+ # output range is generated compare it with the previous range to see
+ # if they can be joined, as applying a rasterop may cause two different
+ # ranges to have the same value.
+
+ x = 1
+ rn_o = RL_FIRST
+ segsize = ds - 1
+ rop_enable = false
+ plr_init (rl_dst, d_dst)
+
+ do i = 1, ARB {
+ # Set up for the next segment (before, in, and after the region to
+ # which the ROP applies), when the current segment is exhausted.
+
+ if (segsize <= 0)
+ if (!rop_enable) {
+ # Begin processing central region.
+ segsize = npix
+ rop_enable = true
+ if (segsize <= 0)
+ next
+ } else {
+ # Begin processing final region.
+ segsize = ARB
+ rop_enable = false
+ }
+
+ # Determine the length of the next output segment. This is the
+ # largest segment of constant value formed by the intersection of
+ # the two lists. If bounds checking has been properly performed
+ # then it should not be possible to see nleft=zero on either input
+ # list. Note that zeroed regions are valid data here.
+
+ np = min (segsize, plr_nleft(d_dst))
+ if (need_src && rop_enable && plr_nleft(d_src) > 0)
+ np = min (np, plr_nleft(d_src))
+ if (np <= 0)
+ break
+
+ # Get the segment value and advance the line pointers. We must
+ # read the DST list whether or not we will use the data, since
+ # the list pointer must be advanced NPIX pixels so that we may
+ # copy the remainder of the list after the loop.
+
+ plr_getseg (rl_dst, d_dst, np, v_dst)
+ if (rop_enable) {
+ # Get v_src.
+ if (need_src) {
+ v_src = 0
+ if (plr_nleft (d_src) > 0)
+ plr_getseg (rl_src, d_src, np, v_src)
+
+ if (R_NOTSRC(rop)) {
+ v_src = not (v_src)
+ if (src_maxval != 0)
+ v_src = and (int(v_src), src_maxval)
+ }
+
+ if (v_src != 0 && src_maxval == 1)
+ v_src = src_value
+ }
+
+ # Get v_dst.
+ if (need_dst) {
+ if (R_NOTDST(rop)) {
+ v_dst = not (v_dst)
+ if (dst_maxval != 0)
+ v_dst = and (int(v_dst), dst_maxval)
+ }
+ }
+
+ # Apply the rasterop.
+ switch (opcode) {
+ case PIX_CLR:
+ pv = 0
+ case PIX_SET:
+ pv = data
+ case PIX_SRC, PIX_NOTSRC:
+ pv = v_src
+ case PIX_DST, PIX_NOTDST:
+ pv = v_dst
+ case PIX_SRC_AND_DST, PIX_SRC_AND_NOTDST, PIX_NOTSRC_AND_DST:
+ pv = and (v_src, v_dst)
+ case PIX_SRC_OR_DST, PIX_SRC_OR_NOTDST, PIX_NOTSRC_OR_DST:
+ pv = or (v_src, v_dst)
+ case PIX_SRC_XOR_DST:
+ pv = xor (v_src, v_dst)
+ case PIX_NOT_SRC_AND_DST:
+ pv = not (and (v_src, v_dst))
+ case PIX_NOT_SRC_OR_DST:
+ pv = not (or (v_src, v_dst))
+ case PIX_NOT_SRC_XOR_DST:
+ pv = not (xor (v_src, v_dst))
+ }
+
+ # Mask the high bits to prevent negative values, or map int
+ # to bool for the case of a boolean output mask.
+
+ if (dst_maxval == 1 && pv != 0)
+ pv = 1
+ else if (dst_maxval > 1)
+ pv = and (int(pv), dst_maxval)
+
+ } else
+ pv = v_dst
+
+ # Output a nonzero range.
+ if (pv > 0) {
+ p = rn_o - 1
+ if (p >= RL_FIRST &&
+ pv == rl_out[3,p] && x == rl_out[1,p] + rl_out[2,p]) {
+ # Merge new range with previous one.
+ rl_out[2,p] = rl_out[2,p] + np
+ } else {
+ rl_out[1,rn_o] = x
+ rl_out[2,rn_o] = np
+ rl_out[3,rn_o] = pv
+ rn_o = rn_o + 1
+ }
+ }
+
+ x = x + np
+ segsize = segsize - np
+ }
+
+ # Update the range list header.
+ call amovi (rl_dst, rl_out, (RL_FIRST - 1) * 3)
+ RL_LEN(rl_out) = rn_o - 1
+end
diff --git a/sys/plio/tf/plrropl.x b/sys/plio/tf/plrropl.x
new file mode 100644
index 00000000..ec936e09
--- /dev/null
+++ b/sys/plio/tf/plrropl.x
@@ -0,0 +1,195 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plset.h>
+include <plio.h>
+include "../plrseg.h"
+
+# PL_RANGEROP -- Rasterop operation between source and destination range lists.
+# The indicated rasterop operation is performed upon the source and destination
+# range lists, writing the result to RL_OUT, which is a copy of RL_DST except
+# for the region affected by the rasterop operation (note that the destination
+# range list cannot be edited in place since it may change size).
+
+procedure pl_rangeropl (rl_src, xs, src_maxval,
+ rl_dst, ds, dst_maxval, rl_out, npix, rop)
+
+long rl_src[3,ARB] #I source range list
+int xs #I starting pixel index in src range list
+int src_maxval #I max pixel value in src mask
+long rl_dst[3,ARB] #I destination range list
+int ds #I starting pixel index in dst range list
+int dst_maxval #I max pixel value in dst mask
+long rl_out[3,ARB] #O output list (edited version of rl_dst)
+int npix #I number of pixels to convert
+int rop #I rasterop
+
+bool need_src, need_dst, rop_enable
+long data, src_value, v_src, v_dst, pv
+int segsize, opcode, x, i, np, rn_o, p
+int d_src[LEN_PLRDES], d_dst[LEN_PLRDES]
+
+begin
+ need_src = R_NEED_SRC(rop)
+ need_dst = R_NEED_DST(rop)
+ opcode = R_OPCODE(rop)
+ data = R_DATA(rop)
+
+ # Pixel value to be used if input mask is boolean.
+ if (src_maxval == 1) {
+ src_value = data
+ if (src_value <= 0)
+ src_value = dst_maxval
+ }
+
+ # Advance to the desired position in the source list, discarding
+ # the unused ranges. The point XS may lie within a range or in a
+ # zero area of the input line.
+
+ if (need_src) {
+ x = 1
+ plr_init (rl_src, d_src)
+ do i = 1, ARB {
+ np = min (plr_nleft(d_src), xs - x)
+ plr_getseg (rl_src, d_src, np, v_src)
+ x = x + np
+ if (x >= xs || np == 0)
+ break
+ }
+ }
+
+ # Advance through both the source and destination lists, extracting
+ # line segments which have a constant value in each input list; the
+ # values for the two lists may differ. Apply the given rasterop to
+ # the source and destination pixel values and write each line segment
+ # as a range to the output list. If the ranges in the two input lists
+ # differ (randomly overlap) then the output list will generally be
+ # more fragmented, i.e., have more ranges of constant value. As each
+ # output range is generated compare it with the previous range to see
+ # if they can be joined, as applying a rasterop may cause two different
+ # ranges to have the same value.
+
+ x = 1
+ rn_o = RL_FIRST
+ segsize = ds - 1
+ rop_enable = false
+ plr_init (rl_dst, d_dst)
+
+ do i = 1, ARB {
+ # Set up for the next segment (before, in, and after the region to
+ # which the ROP applies), when the current segment is exhausted.
+
+ if (segsize <= 0)
+ if (!rop_enable) {
+ # Begin processing central region.
+ segsize = npix
+ rop_enable = true
+ if (segsize <= 0)
+ next
+ } else {
+ # Begin processing final region.
+ segsize = ARB
+ rop_enable = false
+ }
+
+ # Determine the length of the next output segment. This is the
+ # largest segment of constant value formed by the intersection of
+ # the two lists. If bounds checking has been properly performed
+ # then it should not be possible to see nleft=zero on either input
+ # list. Note that zeroed regions are valid data here.
+
+ np = min (segsize, plr_nleft(d_dst))
+ if (need_src && rop_enable && plr_nleft(d_src) > 0)
+ np = min (np, plr_nleft(d_src))
+ if (np <= 0)
+ break
+
+ # Get the segment value and advance the line pointers. We must
+ # read the DST list whether or not we will use the data, since
+ # the list pointer must be advanced NPIX pixels so that we may
+ # copy the remainder of the list after the loop.
+
+ plr_getseg (rl_dst, d_dst, np, v_dst)
+ if (rop_enable) {
+ # Get v_src.
+ if (need_src) {
+ v_src = 0
+ if (plr_nleft (d_src) > 0)
+ plr_getseg (rl_src, d_src, np, v_src)
+
+ if (R_NOTSRC(rop)) {
+ v_src = not (v_src)
+ if (src_maxval != 0)
+ v_src = and (int(v_src), src_maxval)
+ }
+
+ if (v_src != 0 && src_maxval == 1)
+ v_src = src_value
+ }
+
+ # Get v_dst.
+ if (need_dst) {
+ if (R_NOTDST(rop)) {
+ v_dst = not (v_dst)
+ if (dst_maxval != 0)
+ v_dst = and (int(v_dst), dst_maxval)
+ }
+ }
+
+ # Apply the rasterop.
+ switch (opcode) {
+ case PIX_CLR:
+ pv = 0
+ case PIX_SET:
+ pv = data
+ case PIX_SRC, PIX_NOTSRC:
+ pv = v_src
+ case PIX_DST, PIX_NOTDST:
+ pv = v_dst
+ case PIX_SRC_AND_DST, PIX_SRC_AND_NOTDST, PIX_NOTSRC_AND_DST:
+ pv = and (v_src, v_dst)
+ case PIX_SRC_OR_DST, PIX_SRC_OR_NOTDST, PIX_NOTSRC_OR_DST:
+ pv = or (v_src, v_dst)
+ case PIX_SRC_XOR_DST:
+ pv = xor (v_src, v_dst)
+ case PIX_NOT_SRC_AND_DST:
+ pv = not (and (v_src, v_dst))
+ case PIX_NOT_SRC_OR_DST:
+ pv = not (or (v_src, v_dst))
+ case PIX_NOT_SRC_XOR_DST:
+ pv = not (xor (v_src, v_dst))
+ }
+
+ # Mask the high bits to prevent negative values, or map int
+ # to bool for the case of a boolean output mask.
+
+ if (dst_maxval == 1 && pv != 0)
+ pv = 1
+ else if (dst_maxval > 1)
+ pv = and (int(pv), dst_maxval)
+
+ } else
+ pv = v_dst
+
+ # Output a nonzero range.
+ if (pv > 0) {
+ p = rn_o - 1
+ if (p >= RL_FIRST &&
+ pv == rl_out[3,p] && x == rl_out[1,p] + rl_out[2,p]) {
+ # Merge new range with previous one.
+ rl_out[2,p] = rl_out[2,p] + np
+ } else {
+ rl_out[1,rn_o] = x
+ rl_out[2,rn_o] = np
+ rl_out[3,rn_o] = pv
+ rn_o = rn_o + 1
+ }
+ }
+
+ x = x + np
+ segsize = segsize - np
+ }
+
+ # Update the range list header.
+ call amovl (rl_dst, rl_out, (RL_FIRST - 1) * 3)
+ RL_LEN(rl_out) = rn_o - 1
+end
diff --git a/sys/plio/tf/plrrops.x b/sys/plio/tf/plrrops.x
new file mode 100644
index 00000000..b2d9781c
--- /dev/null
+++ b/sys/plio/tf/plrrops.x
@@ -0,0 +1,195 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <plset.h>
+include <plio.h>
+include "../plrseg.h"
+
+# PL_RANGEROP -- Rasterop operation between source and destination range lists.
+# The indicated rasterop operation is performed upon the source and destination
+# range lists, writing the result to RL_OUT, which is a copy of RL_DST except
+# for the region affected by the rasterop operation (note that the destination
+# range list cannot be edited in place since it may change size).
+
+procedure pl_rangerops (rl_src, xs, src_maxval,
+ rl_dst, ds, dst_maxval, rl_out, npix, rop)
+
+short rl_src[3,ARB] #I source range list
+int xs #I starting pixel index in src range list
+int src_maxval #I max pixel value in src mask
+short rl_dst[3,ARB] #I destination range list
+int ds #I starting pixel index in dst range list
+int dst_maxval #I max pixel value in dst mask
+short rl_out[3,ARB] #O output list (edited version of rl_dst)
+int npix #I number of pixels to convert
+int rop #I rasterop
+
+bool need_src, need_dst, rop_enable
+short data, src_value, v_src, v_dst, pv
+int segsize, opcode, x, i, np, rn_o, p
+int d_src[LEN_PLRDES], d_dst[LEN_PLRDES]
+
+begin
+ need_src = R_NEED_SRC(rop)
+ need_dst = R_NEED_DST(rop)
+ opcode = R_OPCODE(rop)
+ data = R_DATA(rop)
+
+ # Pixel value to be used if input mask is boolean.
+ if (src_maxval == 1) {
+ src_value = data
+ if (src_value <= 0)
+ src_value = dst_maxval
+ }
+
+ # Advance to the desired position in the source list, discarding
+ # the unused ranges. The point XS may lie within a range or in a
+ # zero area of the input line.
+
+ if (need_src) {
+ x = 1
+ plr_init (rl_src, d_src)
+ do i = 1, ARB {
+ np = min (plr_nleft(d_src), xs - x)
+ plr_getseg (rl_src, d_src, np, v_src)
+ x = x + np
+ if (x >= xs || np == 0)
+ break
+ }
+ }
+
+ # Advance through both the source and destination lists, extracting
+ # line segments which have a constant value in each input list; the
+ # values for the two lists may differ. Apply the given rasterop to
+ # the source and destination pixel values and write each line segment
+ # as a range to the output list. If the ranges in the two input lists
+ # differ (randomly overlap) then the output list will generally be
+ # more fragmented, i.e., have more ranges of constant value. As each
+ # output range is generated compare it with the previous range to see
+ # if they can be joined, as applying a rasterop may cause two different
+ # ranges to have the same value.
+
+ x = 1
+ rn_o = RL_FIRST
+ segsize = ds - 1
+ rop_enable = false
+ plr_init (rl_dst, d_dst)
+
+ do i = 1, ARB {
+ # Set up for the next segment (before, in, and after the region to
+ # which the ROP applies), when the current segment is exhausted.
+
+ if (segsize <= 0)
+ if (!rop_enable) {
+ # Begin processing central region.
+ segsize = npix
+ rop_enable = true
+ if (segsize <= 0)
+ next
+ } else {
+ # Begin processing final region.
+ segsize = ARB
+ rop_enable = false
+ }
+
+ # Determine the length of the next output segment. This is the
+ # largest segment of constant value formed by the intersection of
+ # the two lists. If bounds checking has been properly performed
+ # then it should not be possible to see nleft=zero on either input
+ # list. Note that zeroed regions are valid data here.
+
+ np = min (segsize, plr_nleft(d_dst))
+ if (need_src && rop_enable && plr_nleft(d_src) > 0)
+ np = min (np, plr_nleft(d_src))
+ if (np <= 0)
+ break
+
+ # Get the segment value and advance the line pointers. We must
+ # read the DST list whether or not we will use the data, since
+ # the list pointer must be advanced NPIX pixels so that we may
+ # copy the remainder of the list after the loop.
+
+ plr_getseg (rl_dst, d_dst, np, v_dst)
+ if (rop_enable) {
+ # Get v_src.
+ if (need_src) {
+ v_src = 0
+ if (plr_nleft (d_src) > 0)
+ plr_getseg (rl_src, d_src, np, v_src)
+
+ if (R_NOTSRC(rop)) {
+ v_src = not (v_src)
+ if (src_maxval != 0)
+ v_src = and (int(v_src), src_maxval)
+ }
+
+ if (v_src != 0 && src_maxval == 1)
+ v_src = src_value
+ }
+
+ # Get v_dst.
+ if (need_dst) {
+ if (R_NOTDST(rop)) {
+ v_dst = not (v_dst)
+ if (dst_maxval != 0)
+ v_dst = and (int(v_dst), dst_maxval)
+ }
+ }
+
+ # Apply the rasterop.
+ switch (opcode) {
+ case PIX_CLR:
+ pv = 0
+ case PIX_SET:
+ pv = data
+ case PIX_SRC, PIX_NOTSRC:
+ pv = v_src
+ case PIX_DST, PIX_NOTDST:
+ pv = v_dst
+ case PIX_SRC_AND_DST, PIX_SRC_AND_NOTDST, PIX_NOTSRC_AND_DST:
+ pv = and (v_src, v_dst)
+ case PIX_SRC_OR_DST, PIX_SRC_OR_NOTDST, PIX_NOTSRC_OR_DST:
+ pv = or (v_src, v_dst)
+ case PIX_SRC_XOR_DST:
+ pv = xor (v_src, v_dst)
+ case PIX_NOT_SRC_AND_DST:
+ pv = not (and (v_src, v_dst))
+ case PIX_NOT_SRC_OR_DST:
+ pv = not (or (v_src, v_dst))
+ case PIX_NOT_SRC_XOR_DST:
+ pv = not (xor (v_src, v_dst))
+ }
+
+ # Mask the high bits to prevent negative values, or map int
+ # to bool for the case of a boolean output mask.
+
+ if (dst_maxval == 1 && pv != 0)
+ pv = 1
+ else if (dst_maxval > 1)
+ pv = and (int(pv), dst_maxval)
+
+ } else
+ pv = v_dst
+
+ # Output a nonzero range.
+ if (pv > 0) {
+ p = rn_o - 1
+ if (p >= RL_FIRST &&
+ pv == rl_out[3,p] && x == rl_out[1,p] + rl_out[2,p]) {
+ # Merge new range with previous one.
+ rl_out[2,p] = rl_out[2,p] + np
+ } else {
+ rl_out[1,rn_o] = x
+ rl_out[2,rn_o] = np
+ rl_out[3,rn_o] = pv
+ rn_o = rn_o + 1
+ }
+ }
+
+ x = x + np
+ segsize = segsize - np
+ }
+
+ # Update the range list header.
+ call amovs (rl_dst, rl_out, (RL_FIRST - 1) * 3)
+ RL_LEN(rl_out) = rn_o - 1
+end