aboutsummaryrefslogtreecommitdiff
path: root/sys/pmio
diff options
context:
space:
mode:
Diffstat (limited to 'sys/pmio')
-rw-r--r--sys/pmio/README284
-rw-r--r--sys/pmio/mio.h56
-rw-r--r--sys/pmio/mioclose.x18
-rw-r--r--sys/pmio/miogl.gx103
-rw-r--r--sys/pmio/mioopen.x31
-rw-r--r--sys/pmio/mioopeno.x30
-rw-r--r--sys/pmio/miopl.gx102
-rw-r--r--sys/pmio/mioseti.x30
-rw-r--r--sys/pmio/miosrange.x33
-rw-r--r--sys/pmio/miostati.x27
-rw-r--r--sys/pmio/mkpkg68
-rw-r--r--sys/pmio/plprop.gx177
-rw-r--r--sys/pmio/pmaccess.x24
-rw-r--r--sys/pmio/pmascii.x27
-rw-r--r--sys/pmio/pmbox.x34
-rw-r--r--sys/pmio/pmcircle.x37
-rw-r--r--sys/pmio/pmclear.x28
-rw-r--r--sys/pmio/pmempty.x27
-rw-r--r--sys/pmio/pmglls.x78
-rw-r--r--sys/pmio/pmglp.gx69
-rw-r--r--sys/pmio/pmglr.gx85
-rw-r--r--sys/pmio/pmio.com5
-rw-r--r--sys/pmio/pmline.x36
-rw-r--r--sys/pmio/pmlinene.x28
-rw-r--r--sys/pmio/pmnewmask.x28
-rw-r--r--sys/pmio/pmplls.x103
-rw-r--r--sys/pmio/pmplp.gx34
-rw-r--r--sys/pmio/pmplr.gx34
-rw-r--r--sys/pmio/pmpoint.x31
-rw-r--r--sys/pmio/pmpolygon.x42
-rw-r--r--sys/pmio/pmrio.x128
-rw-r--r--sys/pmio/pmrop.x74
-rw-r--r--sys/pmio/pmsectnc.x35
-rw-r--r--sys/pmio/pmsectne.x32
-rw-r--r--sys/pmio/pmseti.x30
-rw-r--r--sys/pmio/pmsplane.x22
-rw-r--r--sys/pmio/pmstati.x32
-rw-r--r--sys/pmio/pmsten.x77
-rw-r--r--sys/pmio/tf/miogld.x103
-rw-r--r--sys/pmio/tf/miogli.x103
-rw-r--r--sys/pmio/tf/miogll.x103
-rw-r--r--sys/pmio/tf/mioglr.x103
-rw-r--r--sys/pmio/tf/miogls.x103
-rw-r--r--sys/pmio/tf/mioglx.x103
-rw-r--r--sys/pmio/tf/miopld.x102
-rw-r--r--sys/pmio/tf/miopli.x102
-rw-r--r--sys/pmio/tf/miopll.x102
-rw-r--r--sys/pmio/tf/mioplr.x102
-rw-r--r--sys/pmio/tf/miopls.x102
-rw-r--r--sys/pmio/tf/mioplx.x102
-rw-r--r--sys/pmio/tf/mkpkg33
-rw-r--r--sys/pmio/tf/pmglpi.x69
-rw-r--r--sys/pmio/tf/pmglpl.x69
-rw-r--r--sys/pmio/tf/pmglps.x69
-rw-r--r--sys/pmio/tf/pmglri.x81
-rw-r--r--sys/pmio/tf/pmglrl.x81
-rw-r--r--sys/pmio/tf/pmglrs.x81
-rw-r--r--sys/pmio/tf/pmplpi.x34
-rw-r--r--sys/pmio/tf/pmplpl.x34
-rw-r--r--sys/pmio/tf/pmplps.x34
-rw-r--r--sys/pmio/tf/pmplri.x34
-rw-r--r--sys/pmio/tf/pmplrl.x34
-rw-r--r--sys/pmio/tf/pmplrs.x34
-rw-r--r--sys/pmio/zzdebug.x217
-rw-r--r--sys/pmio/zzinterp.x1142
65 files changed, 5415 insertions, 0 deletions
diff --git a/sys/pmio/README b/sys/pmio/README
new file mode 100644
index 00000000..303c464b
--- /dev/null
+++ b/sys/pmio/README
@@ -0,0 +1,284 @@
+PMIO -- The Pixel Mask I/O package (PLIO for image masks).
+PLIO -- The Pixel List I/O package (no ties to IMIO)
+
+ A PIXEL LIST is a compressed, region oriented data structure used to store
+an image matrix. The pixel list package is used to create, manage, and access
+this data structure. Although the PLIO package can stand alone and is useful
+in its own right, one of the main uses of the pixel list package is in the IMIO
+interface, which can access a pixel list as if it were a MASK IMAGE.
+See PLIO.hlp for further information on the PLIO package and image masks.
+
+The pixel list package itself does not support any fancy image coordinate
+transformations. If an image has an associated pixel mask, the pixel mask
+refers to the physical image matrix. An application written at the IMIO level
+where an image section transformation may be defined for an image should
+normally use the PMIO (pixel mask) package in preference to PLIO. PMIO is
+equivalent to PLIO, except that coordinates are input in image section
+coordinates, and a reference image is used to map such coordinates onto the
+physical image matrix.
+
+
+1. IMIO Mask Image Interface
+
+ im = im_pmmap (maskname, mode, ref_im|NULL)
+ im = im_pmmapo (pm, ref_im)
+
+ imseti (im, IM_RLIO, YES|NO) # enable range list i/o
+ imseti (im, IM_PMDES, pm) # inquire PM descriptor
+ pm = imstati (im, IM_PMDES)
+
+ bool = im_pmlne[123] (im[, lineno[, bandno]])
+ bool = im_pmsne[123] (im, x1, x2[, y1, y2[, z1, z2]])
+ bool = im_pmlnev (im, v)
+ bool = im_pmsnev (im, vs, ve, ndim)
+
+ mp = mio_open (maskname, flags, im) # Masked Image I/O
+ mp = mio_openo (pm, im)
+ value = mio_stati (mp, param)
+ mio_seti (mp, param, value)
+ mio_setrange (mp, vs, ve, ndim)
+ n|EOF = mio_[gp]lseg[silrdx] (mp, ptr, mval, v, npix)
+ mio_close (mp)
+
+
+2. Pixel Mask Interface (uses reference image for section transformation)
+
+ pm = pm_newmask (ref_im, depth)
+
+ pm = pm_open (bufptr|NULL)
+ pm = pm_create (naxes, axlen, depth)
+ pm = pm_newcopy (pm)
+ pm_close (pm)
+
+ pm_[sg]size (pm, naxes, alxen, depth)
+ pm_seti (pm, param, value)
+ value = pm_stati (pm, param)
+ pm_debug (pm, outfd, maxcol, flags)
+ bool = pm_empty (pm)
+ pm_compress (pm)
+ pm_clear (pm)
+
+ pm_load (pm, bufptr)
+ nwords = pm_save (pm, bufptr, buflen, save_flags)
+ pm_loadf (pm, fname, title, maxch)
+ pm_savef (pm, fname, title, save_flags)
+ pm_[load|save]im (pm, imname[, save_flags])
+
+ ptr = pm_access (pm, v)
+ bool = pm_linenotempty (pm, v)
+ bool = pm_sectnotempty (pm, vs, ve, ndim)
+ pm[gp]l[lrp][sil] (pm, v, buf, b_depth, npix, rop)
+
+ pm_[set|get]plane (pm, v)
+ pm_point (pm, x, y, rop)
+ pm_circle (pm, x, y, r, rop)
+ pm_box (pm, x1,y1, x2,y2, rop)
+ pm_line (pm, x1,y1, x2,y2, width, rop)
+ pm_polygon (pm, x, y, npts, rop)
+
+ pm_rop (pm_src, vs, pm_dst, vs, vn, rop)
+ pm_stencil (pm_src, vs, pm_dst, vs, pm_stl, vs, vn, rop)
+
+
+2.1 Random Access to a Pixel Mask
+
+ pmr = pmr_open (pm, plane, buflimit)
+ pmr_setrect (pmr, x1,y1, x2,y2)
+ mval = pmr_getpix (pmr, i, j)
+ pmr_close (pmr)
+
+
+3. Pixel List Interface (stands alone; independent of IMIO; no coord xforms)
+
+ pl = pl_open (bufptr|NULL)
+ pl = pl_create (naxes, axlen, depth)
+ pl = pl_newcopy (pl)
+ pl_close (pl)
+
+ pl_[sg]size (pl, naxes, axlen, depth)
+ pl_seti (pl, param, value)
+ value = pl_stati (pl, param)
+ pl_debug (pl, outfd, maxcol, flags)
+ bool = pl_empty (pl)
+ pl_compress (pl)
+ pl_clear (pl)
+
+ pl_load (pl, bufptr)
+ nwords = pl_save (pl, bufptr, buflen, save_flags)
+ pl_loadf (pl, fname, title, maxch)
+ pl_savef (pl, fname, title, save_flags)
+ pl_[load|save]im (pl, imname[, save_flags])
+
+ ptr = pl_access (pl, v)
+ bool = pl_linenotempty (pl, v)
+ bool = pl_sectnotempty (pl, vs, ve, ndim)
+ pl[gp]l[lrp][sil] (pl, v, buf, b_depth, npix, rop)
+
+ pl_[set|get]plane (pl, v)
+ pl_point (pl, x, y, rop)
+ pl_circle (pl, x, y, r, rop)
+ pl_box (pl, x1,y1, x2,y2, rop)
+ pl_line (pl, x1,y1, x2,y2, width, rop)
+ pl_polygon (pl, x, y, npts, rop)
+
+ pl_rop (pl_src, vs, pl_dst, vs, vn, rop)
+ pl_stencil (pl_src, vs, pl_dst, vs, pl_stl, vs, vn, rop)
+
+
+3.1 Random Access to a Pixel List
+
+ plr = plr_open (pl, plane, buflimit)
+ plr_setrect (plr, x1,y1, x2,y2)
+ mval = plr_getpix (plr, i, j)
+ plr_getlut (plr, bufp, xsize,ysize, xblock,yblock)
+ plr_close (plr)
+
+
+3.2 Pixel, Line, and Range List Routines
+
+ pl_pixrop (px_src, xs, src_maxval,
+ px_dst, ds, dst_maxval, npix, rop)
+ pl_linerop (ll_src, xs, src_maxval,
+ ll_dst, ds, dst_maxval, ll_out, npix, rop)
+ pl_rangerop (rl_src, xs, src_maxval,
+ rl_dst, ds, dst_maxval, rl_out, npix, rop)
+ pl_linestencil (ll_src, xs, src_maxval, ll_dst, ds, dst_maxval,
+ ll_stn, xs, ll_out, npix, rop)
+
+ n = pl_[lrp]2[lrp][sil] (op_src, xs, op_dst, npix)
+
+
+4. EXAMPLE
+
+4.1 Sample Mask (pl_draw output)
+
+ 40 .1111111..............................................................22222
+ 39 .1111111..............................................................22222
+ 38 .1111111...............................................................2222
+ 37 .1111111...............................................................2222
+ 36 .1111111............................................................4......
+ 35 .1111111.....................11111111111111111111111111...........4444.....
+ 34 .1111111.....................11111111111111111111111111........44444444....
+ 33 .1111111......................1111111111111111111111111......44444444......
+ 32 .1111111......................1111111111111111111111111...44444444.........
+ 31 .1111111......................1111111111111111111111111.44444444...........
+ 30 .1111111...........4..........1111111111111111111111115444444..............
+ 29 .1111111...........4..........11111111111111111111155554444................
+ 28 .1111111...........4..........111111111111111111155555544..................
+ 27 .1111111...........4..........1111111111111111555555551....................
+ 26 .1111111.....................11111111111111155555555111....................
+ 25 .1111111.....................11111111111115555555111111....................
+ 24 ............................1111111111155444444.1111111....................
+ 23 ...........................111111111155544444....111111....................
+ 22 ..............1...........1111111155555444........11111....................
+ 21 ........................1111111155555554..........11111....................
+ 20 ........................111111555555511...........11111....................
+ 19 ........................111555555551111...........11111....................
+ 18 ........................155555555111111...........11111....................
+ 17 ......................445555551111111111.........111111....................
+ 16 ....................444455551111111111111.......1111111....................
+ 15 ..................4444445111111111111111111111111111111....................
+ 14 ...............44444444.1111111111111111111111111111111....................
+ 13 .............44444444......................................................
+ 12 ..........44444444.........................................................
+ 11 ........44444444...........................................................
+ 10 .........4444........................22222.................................
+ 9 ..........4.........................2222222..............22222.............
+ 8 ....................................2222222.............2222222............
+ 7 ....................................2222222.............2222222............
+ 6 .....................................22222..............2222222............
+ 5 11111111111111111111.....................................22222.............
+ 4 11111111111111111111.......................................................
+ 3 11111111111111111111.......................................................
+ 2 11111111111111111111.......................................................
+ 1 11111111111111111111.......................................................
+ 123456789012345678901234567890123456789012345678901234567890123456789012345
+ 1 2 3 4 5 6 7
+
+
+4.2 Sample Debug Output (for above mask)
+
+Mask 1EECD naxes=2 [75,40] maxval=177 plane=[75,40]
+max buffered line size 1024, max actual line size 16
+40 lines total, 40 are nonempty, mask is nonempty
+llbp=42AF5, len=1190, op=583, free=189, nupdates=35
+Index at 1EFF1 containing 40 lines:
+ 4 4 4 4 17 26 35 35 166 177 187
+ 194 201 208 218 228 241 254 266 554 292 568
+ 319 333 347 360 492 507 523 539 423 435 447
+ 459 471 483 148 148 157 157
+Line list containing 40 lines:
+[1:4] IH48(49) H20 Z55 (75,49)
+[5] IH48(49) H20 IH1(50) Z37 H5 Z13 (75,50)
+[6] IH49(50) Z37 H5 Z14 H7 Z12 (75,50)
+[7:8] IH49(50) Z36 H7 Z13 H7 Z12 (75,50)
+[9] IH51(52) P11 DH2(50) Z25 H7 Z14 H5 Z13 (75,50)
+[10] IH51(52) Z9 H4 DH2(50) Z24 H5 Z33 (75,50)
+[11] IH51(52) Z8 H8 Z59 (75,52)
+[12] IH51(52) Z10 H8 Z57 (75,52)
+[13] IH51(52) Z13 H8 Z54 (75,52)
+[14] IH51(52) Z15 H8 DH3(49) Z1 H31 Z20 (75,49)
+[15] IH51(52) Z18 H6 IS1(53) DH4(49) H30 Z20 (75,49)
+[16] IH51(52) Z20 H4 IH1(53) H4 DH4(49) H13 Z7 H7 Z20 (75,49)
+[17] IH51(52) Z22 H2 IH1(53) H6 DH4(49) H10 Z9 H6 Z20 (75,49)
+[18] IH48(49) P25 IH4(53) H8 DH4(49) H6 Z11 H5 Z20 (75,49)
+[19] IH48(49) Z24 H3 IH4(53) H8 DH4(49) H4 Z11 H5 Z20 (75,49)
+[20] IH48(49) Z24 H6 IH4(53) H7 DH4(49) H2 Z11 H5 Z20 (75,49)
+[21] IH48(49) Z24 H8 IH4(53) H7 DS1(52) DH3(49) Z10 H5 Z20 (75,49)
+[22] IH48(49) P15 Z11 H8 IH4(53) H5 DH1(52) H3 DH3(49) Z8 H5 Z20 (75,49)
+[23] IH48(49) Z27 H10 IH4(53) H3 DH1(52) H5 DH3(49) Z4 H6 Z20 (75,49)
+[24] IH48(49) Z28 H11 IH4(53) H2 DH1(52) H6 DH3(49) Z1 H7 Z20 (75,49)
+[25] IH48(49) Z1 H7 Z21 H13 IH4(53) H7 DH4(49) H6 Z20 (75,49)
+[26] IH48(49) Z1 H7 Z21 H15 IH4(53) H8 DH4(49) H3 Z20 (75,49)
+[27] IH48(49) Z1 H7 IH3(52) P12 DH3(49) Z10 H16 IH4(53) H8 DS4(49) Z20
+ (75,49)
+[28] IH48(49) Z1 H7 IH3(52) P12 DH3(49) Z10 H19 IH4(53) H6 DH1(52) H2 Z18
+ (75,52)
+[29] IH48(49) Z1 H7 IH3(52) P12 DH3(49) Z10 H21 IH4(53) H4 DH1(52) H4 Z16
+ (75,52)
+[30] IH48(49) Z1 H7 IH3(52) P12 DH3(49) Z10 H24 IS4(53) DH1(52) H6 Z14
+ (75,52)
+[31] IH48(49) Z1 H7 Z22 H25 IH3(52) Z1 H8 Z11 (75,52)
+[32] IH48(49) Z1 H7 Z22 H25 IH3(52) Z3 H8 Z9 (75,52)
+[33] IH48(49) Z1 H7 Z22 H25 IH3(52) Z6 H8 Z6 (75,52)
+[34] IH48(49) Z1 H7 Z21 H26 IH3(52) Z8 H8 Z4 (75,52)
+[35] IH48(49) Z1 H7 Z21 H26 IH3(52) Z11 H4 Z5 (75,52)
+[36] IH48(49) Z1 H7 IH3(52) P61 Z6 (75,52)
+[37:38] IH48(49) Z1 H7 IH1(50) Z63 H4 (75,50)
+[39:40] IH48(49) Z1 H7 IH1(50) Z62 H5 (75,50)
+
+Line list containing 40 lines:
+[1:4] 1-20(49)
+[5] 1-20(49) 58-62(50)
+[6] 38-42(50) 57-63(50)
+[7:8] 37-43(50) 57-63(50)
+[9] 11(52) 37-43(50) 58-62(50)
+[10] 10-13(52) 38-42(50)
+[11] 9-16(52)
+[12] 11-18(52)
+[13] 14-21(52)
+[14] 16-23(52) 25-55(49)
+[15] 19-24(52) 25(53) 26-55(49)
+[16] 21-24(52) 25-28(53) 29-41(49) 49-55(49)
+[17] 23-24(52) 25-30(53) 31-40(49) 50-55(49)
+[18] 25(49) 26-33(53) 34-39(49) 51-55(49)
+[19] 25-27(49) 28-35(53) 36-39(49) 51-55(49)
+[20] 25-30(49) 31-37(53) 38-39(49) 51-55(49)
+[21] 25-32(49) 33-39(53) 40(52) 51-55(49)
+[22] 15(49) 27-34(49) 35-39(53) 40-42(52) 51-55(49)
+[23] 28-37(49) 38-40(53) 41-45(52) 50-55(49)
+[24] 29-39(49) 40-41(53) 42-47(52) 49-55(49)
+[25] 2-8(49) 30-42(49) 43-49(53) 50-55(49)
+[26] 2-8(49) 30-44(49) 45-52(53) 53-55(49)
+[27] 2-8(49) 20(52) 31-46(49) 47-54(53) 55(49)
+[28] 2-8(49) 20(52) 31-49(49) 50-55(53) 56-57(52)
+[29] 2-8(49) 20(52) 31-51(49) 52-55(53) 56-59(52)
+[30] 2-8(49) 20(52) 31-54(49) 55(53) 56-61(52)
+[31] 2-8(49) 31-55(49) 57-64(52)
+[32] 2-8(49) 31-55(49) 59-66(52)
+[33] 2-8(49) 31-55(49) 62-69(52)
+[34] 2-8(49) 30-55(49) 64-71(52)
+[35] 2-8(49) 30-55(49) 67-70(52)
+[36] 2-8(49) 69(52)
+[37:38] 2-8(49) 72-75(50)
+[39:40] 2-8(49) 71-75(50)
diff --git a/sys/pmio/mio.h b/sys/pmio/mio.h
new file mode 100644
index 00000000..11e4c9d0
--- /dev/null
+++ b/sys/pmio/mio.h
@@ -0,0 +1,56 @@
+# MIO -- Image i/o through a mask.
+#
+# The MIO routines are used to sequentially read or write the portion of
+# the image IM which is "visible" through the mask denoted by the mask name
+# PLNAME or the open mask descriptor PM. An image pixel is said to be visible
+# if the associated mask pixel is nonzero. The PMIO routines may be used prior
+# to performing any i/o to prepare the desired mask, e.g., a mask might be
+# inverted to access only the "masked" pixels, or a mask might be ANDed with a
+# region to limit i/o to only the portions of the image visible through both
+# the mask and the region. Certain commonly performed mask conversions may be
+# performed at MIO_OPEN time via the FLAGS argument, e.g., inversion, or
+# conversion of an integer mask to a boolean mask.
+#
+# mp = mio_open (mask, flags, im)
+# mp = mio_openo (pm, im)
+# value = mio_stati (mp, param)
+# mio_seti (mp, param, value)
+# mio_setrange (mp, vs, ve, ndim)
+# n|EOF = mio_[gp]lseg[silrdx] (mp, ptr, mval, v, npix)
+# mio_close (mp)
+#
+# mio_open flags (defined in <pmset.h>):
+#
+# INVERT_MASK invert mask (PIX_NOT(PIX_SRC))
+# BOOLEAN_MASK convert mask to boolean if not already
+#
+# set/stat params (defined in <pmset.h>):
+#
+# P_PMDES pixel mask descriptor
+# P_IMDES image descriptor
+# P_REGCOORDS mio_setrange region relative coords
+#
+# The get/put line segment i/o routines return successive line segments of
+# constant value from the data image IM, advancing through the image in storage
+# order starting at the position vector [1,1,1...,N]. A pointer to each line
+# segment is returned in PTR, with the associated integer mask value in MVAL,
+# and the vector coordinates and length of the line segment in V and NPIX.
+# EOF is returned when there are no more visible pixels to be read through the
+# masked region.
+
+define LEN_MIODES 50
+define M_IM Memi[$1] # image descriptor
+define M_PM Memi[$1+1] # mask descriptor
+define M_PMCLOSE Memi[$1+2] # have mio_close close mask
+define M_DEPTH Memi[$1+3] # have mio_close close mask
+define M_ACTIVE Memi[$1+4] # set once i/o begins
+define M_LBP Memi[$1+5] # line buffer pointer
+define M_RLP Memi[$1+6] # range list pointer
+define M_RLI Memi[$1+7] # range list index
+define M_NDIM Memi[$1+8] # dimensionality of section
+define M_LINEIO Memi[$1+9] # section is entire line
+define M_REGCOORDS Memi[$1+10] # region relative coords
+define M_V Meml[$1+11+$2-1] # current vector
+define M_VS Meml[$1+20+$2-1] # start vector
+define M_VE Meml[$1+30+$2-1] # end vector
+define M_VN Meml[$1+40+$2-1] # size of section
diff --git a/sys/pmio/mioclose.x b/sys/pmio/mioclose.x
new file mode 100644
index 00000000..7b321512
--- /dev/null
+++ b/sys/pmio/mioclose.x
@@ -0,0 +1,18 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include "mio.h"
+
+# MIO_CLOSE -- Close an MIO descriptor.
+
+procedure mio_close (mp)
+
+pointer mp #I MIO descriptor
+
+begin
+ if (M_PMCLOSE(mp) == YES)
+ call pm_close (M_PM(mp))
+ if (M_RLP(mp) != NULL)
+ call mfree (M_RLP(mp), TY_INT)
+ call mfree (mp, TY_STRUCT)
+end
diff --git a/sys/pmio/miogl.gx b/sys/pmio/miogl.gx
new file mode 100644
index 00000000..3b02710e
--- /dev/null
+++ b/sys/pmio/miogl.gx
@@ -0,0 +1,103 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include <plio.h>
+include "../mio.h"
+
+# MIO_GLSEG -- Get a line segment from a masked image. A line segment is a
+# region of the data image for which the corresponding region of the mask has
+# the constant nonzero value MVAL. Line segments are returned for each line in
+# the region VS to VE, returning the number of pixels in each line segment as
+# the function value, or EOF when the region is exhausted. Once EOF is
+# reached, repeated calls will continue to return EOF until the next call to
+# MIO_SETRANGE. Repeated calls to MIO_SETRANGE may be used to access a series
+# of distinct regions in the image. If a subregion of the image is being
+# accessed with MIO_SETRANGE, the vector coordinates V returned below will
+# be relative to the defined subregion (if this is not what is desired,
+# the range should be set to the full image and a region mask used to mask
+# off the subregion to be accessed).
+
+int procedure mio_glseg$t (mp, ptr, mval, v, npix)
+
+pointer mp #I MIO descriptor
+pointer ptr #O pointer to a buffer containing the data
+int mval #O mask value for the output line segment
+long v[IM_MAXDIM] #U coords of first pixel in output ine segment
+int npix #O number of pixels in output line segment
+
+int x1, i
+long ve[IM_MAXDIM]
+pointer pm, im, rl, rp, bp
+pointer imgl2$t(), imgl3$t(), imggs$t()
+errchk imgl2$t, imgl3$t, imggs$t, pm_glri
+bool pm_sectnotempty()
+int plloop()
+
+begin
+ pm = M_PM(mp)
+ rl = M_RLP(mp)
+
+ # Initialization performed for the first i/o on a new region.
+ if (M_ACTIVE(mp) == NO) {
+ call plsslv (pm, M_VS(mp,1), M_VN(mp,1), M_V(mp,1), M_VE(mp,1))
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ M_ACTIVE(mp) = YES
+ }
+
+ # Get a new mask line?
+ while (M_RLI(mp) > RLI_LEN(rl))
+ if (plloop (M_V(mp,1), M_VS(mp,1), M_VE(mp,1),
+ M_NDIM(mp)) == LOOP_DONE) {
+ return (EOF)
+ } else {
+ call amovl (M_V(mp,1), ve, M_NDIM(mp))
+ ve[1] = M_VE(mp,1)
+ if (pm_sectnotempty (pm, M_V(mp,1), ve, M_NDIM(mp))) {
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ }
+ }
+
+ # Get a new image line?
+ if (M_RLI(mp) == RL_FIRST) {
+ call amovl (M_V(mp,1), v, M_NDIM(mp))
+ im = M_IM(mp)
+
+ if (M_LINEIO(mp) == YES && M_NDIM(mp) == 2)
+ bp = imgl2$t (im, v[2])
+ else if (M_LINEIO(mp) == YES && M_NDIM(mp) == 3)
+ bp = imgl3$t (im, v[2], v[3])
+ else {
+ call amovl (v, ve, M_NDIM(mp)); ve[1] = M_VE(mp,1)
+ bp = imggs$t (im, v, ve, M_NDIM(mp))
+ }
+
+ M_LBP(mp) = bp
+ } else
+ bp = M_LBP(mp)
+
+ # Return the next line segment.
+ rp = rl + (M_RLI(mp) - 1) * RL_LENELEM
+ M_RLI(mp) = M_RLI(mp) + 1
+
+ x1 = Memi[rp+RL_XOFF]
+ npix = Memi[rp+RL_NOFF]
+ mval = Memi[rp+RL_VOFF]
+ ptr = bp + x1 - M_VS(mp,1)
+
+ if (M_REGCOORDS(mp) == NO) {
+ v[1] = x1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i)
+ } else {
+ v[1] = x1 - M_VS(mp,1) + 1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i) - M_VS(mp,i) + 1
+ }
+
+ return (npix)
+end
diff --git a/sys/pmio/mioopen.x b/sys/pmio/mioopen.x
new file mode 100644
index 00000000..b22c2022
--- /dev/null
+++ b/sys/pmio/mioopen.x
@@ -0,0 +1,31 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include "mio.h"
+
+# MIO_OPEN -- Open a pixel mask for masked i/o on the given data image.
+# The data image also serves as the reference image for coordinate (section)
+# transformations.
+
+pointer procedure mio_open (mask, flags, im)
+
+char mask[ARB] #I mask name
+int flags #I flag bits
+pointer im #I data (and reference) image
+
+pointer pm, mp
+char title[1]
+pointer im_pmopen(), mio_openo()
+errchk im_pmopen
+
+begin
+ pm = im_pmopen (mask, flags, title, 0, im)
+ mp = mio_openo (pm, im)
+
+ M_PMCLOSE(mp) = YES
+ M_DEPTH(mp) = PM_MAXDEPTH
+ if (and (flags, BOOLEAN_MASK) != 0)
+ M_DEPTH(mp) = 1
+
+ return (mp)
+end
diff --git a/sys/pmio/mioopeno.x b/sys/pmio/mioopeno.x
new file mode 100644
index 00000000..bd3a6a96
--- /dev/null
+++ b/sys/pmio/mioopeno.x
@@ -0,0 +1,30 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include "mio.h"
+
+# MIO_OPENO -- Open an MIO descriptor for the given mask and data image.
+
+pointer procedure mio_openo (pm, im)
+
+pointer pm #I mask descriptor
+pointer im #I image descriptor
+
+pointer mp
+
+begin
+ call calloc (mp, LEN_MIODES, TY_STRUCT)
+ call malloc (M_RLP(mp), RL_MAXLEN(pm), TY_INT)
+ RLI_LEN(M_RLP(mp)) = 0
+
+ call amovkl (1, M_VS(mp,1), IM_MAXDIM)
+ call amovl (IM_LEN(im,1), M_VN(mp,1), IM_MAXDIM)
+
+ M_IM(mp) = im
+ M_PM(mp) = pm
+ call pm_seti (pm, P_REFIM, im)
+ call mio_setrange (mp, M_VS(mp,1), M_VN(mp,1), IM_NDIM(im))
+
+ return (mp)
+end
diff --git a/sys/pmio/miopl.gx b/sys/pmio/miopl.gx
new file mode 100644
index 00000000..be7b7b95
--- /dev/null
+++ b/sys/pmio/miopl.gx
@@ -0,0 +1,102 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include <plio.h>
+include "../mio.h"
+
+# MIO_PLSEG -- Put a line segment to a masked image. A line segment is a
+# region of the data image for which the corresponding region of the mask has
+# the constant nonzero value MVAL. Line segments are returned for each line in
+# the region VS to VE, returning the number of pixels in each line segment as
+# the function value, or EOF when the region is exhausted. Once EOF is
+# reached, repeated calls will continue to return EOF until the next call to
+# MIO_SETRANGE. Repeated calls to MIO_SETRANGE may be used to access a series
+# of distinct regions in the image. If a subregion of the image is being
+# accessed with MIO_SETRANGE, the vector coordinates V returned below will
+# be relative to the defined subregion (if this is not what is desired,
+# the range should be set to the full image and a region mask used to mask
+# off the subregion to be accessed).
+
+int procedure mio_plseg$t (mp, ptr, mval, v, npix)
+
+pointer mp #I MIO descriptor
+pointer ptr #O pointer to a buffer containing the data
+int mval #O mask value for the output line segment
+long v[IM_MAXDIM] #U vector coordinates of first pixel
+int npix #O number of pixels in output line segment
+
+int x1, i
+long ve[IM_MAXDIM]
+pointer pm, im, rl, rp, bp
+pointer impl2$t(), impl3$t(), impgs$t()
+errchk impl2$t, impl3$t, impgs$t, pm_glri
+bool pm_sectnotempty()
+int plloop()
+
+begin
+ pm = M_PM(mp)
+ rl = M_RLP(mp)
+
+ # Initialization performed for the first i/o on a new region.
+ if (M_ACTIVE(mp) == NO) {
+ call plsslv (pm, M_VS(mp,1), M_VN(mp,1), M_V(mp,1), M_VE(mp,1))
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ M_ACTIVE(mp) = YES
+ }
+
+ # Get a new mask line?
+ while (M_RLI(mp) > RLI_LEN(rl))
+ if (plloop (M_V(mp,1), M_VS(mp,1), M_VE(mp,1),
+ M_NDIM(mp)) == LOOP_DONE) {
+ return (EOF)
+ } else {
+ call amovl (M_V(mp,1), ve, M_NDIM(mp))
+ ve[1] = M_VE(mp,1)
+ if (pm_sectnotempty (pm, M_V(mp,1), ve, M_NDIM(mp))) {
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ }
+ }
+
+
+ # Get a new image line?
+ if (M_RLI(mp) == RL_FIRST) {
+ call amovl (M_V(mp,1), v, IM_MAXDIM)
+ im = M_IM(mp)
+
+ if (M_LINEIO(mp) == YES && M_NDIM(mp) == 2)
+ bp = impl2$t (im, v[2])
+ else if (M_LINEIO(mp) == YES && M_NDIM(mp) == 3)
+ bp = impl3$t (im, v[2], v[3])
+ else
+ bp = impgs$t (im, v, ve, M_NDIM(mp))
+
+ M_LBP(mp) = bp
+ } else
+ bp = M_LBP(mp)
+
+ # Return the next line segment.
+ rp = rl + (M_RLI(mp) - 1) * RL_LENELEM
+ M_RLI(mp) = M_RLI(mp) + 1
+
+ x1 = Memi[rp+RL_XOFF]
+ npix = Memi[rp+RL_NOFF]
+ mval = Memi[rp+RL_VOFF]
+ ptr = bp + x1 - M_VS(mp,1)
+
+ if (M_REGCOORDS(mp) == NO) {
+ v[1] = x1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i)
+ } else {
+ v[1] = x1 - M_VS(mp,1) + 1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i) - M_VS(mp,i) + 1
+ }
+
+ return (npix)
+end
diff --git a/sys/pmio/mioseti.x b/sys/pmio/mioseti.x
new file mode 100644
index 00000000..ef4fe116
--- /dev/null
+++ b/sys/pmio/mioseti.x
@@ -0,0 +1,30 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <syserr.h>
+include <pmset.h>
+include "mio.h"
+
+# MIO_SETI -- Set an MIO parameter.
+
+procedure mio_seti (mp, param, value)
+
+pointer mp #I MIO descriptor
+int param #I parameter to be set
+int value #I new value
+
+begin
+ switch (param) {
+ case P_PMDES:
+ M_PM(mp) = value
+ M_ACTIVE(mp) = NO
+ case P_IMDES:
+ M_IM(mp) = value
+ M_ACTIVE(mp) = NO
+ case P_REGCOORDS:
+ M_REGCOORDS(mp) = value
+ case P_PMCLOSE:
+ M_PMCLOSE(mp) = value
+ default:
+ call syserr (SYS_PLINVPAR)
+ }
+end
diff --git a/sys/pmio/miosrange.x b/sys/pmio/miosrange.x
new file mode 100644
index 00000000..26b42727
--- /dev/null
+++ b/sys/pmio/miosrange.x
@@ -0,0 +1,33 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include "mio.h"
+
+# MIO_SETRANGE -- Set the region of the image to be accessed, and rewind the
+# i/o pointer to the beginning of the specified region.
+
+procedure mio_setrange (mp, vs, ve, ndim)
+
+pointer mp #I MIO descriptor
+long vs[IM_MAXDIM] #I vector coords of start of region
+long ve[IM_MAXDIM] #I vector coords of end of region
+int ndim #I dimensionality of region
+
+int i
+int btoi()
+
+begin
+ do i = 1, IM_MAXDIM
+ if (i <= ndim) {
+ M_VS(mp,i) = min (vs[i], ve[i])
+ M_VN(mp,i) = abs (ve[i] - vs[i]) + 1
+ } else {
+ M_VS(mp,i) = 1
+ M_VN(mp,i) = 1
+ }
+
+ M_LINEIO(mp) = btoi (vs[1] == 1 && ve[1] == IM_LEN(M_IM(mp),1))
+ M_REGCOORDS(mp) = YES
+ M_ACTIVE(mp) = NO
+ M_NDIM(mp) = ndim
+end
diff --git a/sys/pmio/miostati.x b/sys/pmio/miostati.x
new file mode 100644
index 00000000..3f492daa
--- /dev/null
+++ b/sys/pmio/miostati.x
@@ -0,0 +1,27 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <syserr.h>
+include <pmset.h>
+include "mio.h"
+
+# MIO_STATI -- Stat an MIO parameter.
+
+int procedure mio_stati (mp, param)
+
+pointer mp #I MIO descriptor
+int param #I parameter to be set
+
+begin
+ switch (param) {
+ case P_PMDES:
+ return (M_PM(mp))
+ case P_IMDES:
+ return (M_IM(mp))
+ case P_REGCOORDS:
+ return (M_REGCOORDS(mp))
+ case P_PMCLOSE:
+ return (M_PMCLOSE(mp))
+ default:
+ call syserr (SYS_PLINVPAR)
+ }
+end
diff --git a/sys/pmio/mkpkg b/sys/pmio/mkpkg
new file mode 100644
index 00000000..0c03f90d
--- /dev/null
+++ b/sys/pmio/mkpkg
@@ -0,0 +1,68 @@
+# Make the PM package library.
+
+$checkout libex.a lib$
+$update libex.a
+$checkin libex.a lib$
+$exit
+
+tfiles:
+ $set PFLAGS = "-k -t silrdx -p tf/"
+ $set GFLAGS = "-k -t sil -p tf/"
+ $ifolder (tf/miogli.x, miogl.gx) $generic $(PFLAGS) miogl.gx $endif
+ $ifolder (tf/miopli.x, miopl.gx) $generic $(PFLAGS) miopl.gx $endif
+ $ifolder (tf/pmglpi.x, pmglp.gx) $generic $(GFLAGS) pmglp.gx $endif
+ $ifolder (tf/pmglri.x, pmglr.gx) $generic $(GFLAGS) pmglr.gx $endif
+ $ifolder (tf/pmplpi.x, pmplp.gx) $generic $(GFLAGS) pmplp.gx $endif
+ $ifolder (tf/pmplri.x, pmplr.gx) $generic $(GFLAGS) pmplr.gx $endif
+ ;
+
+zzdebug:
+zzdebug.e:
+ $set XFLAGS = "$(XFLAGS) -q"
+ $omake zzinterp.x <error.h> <ctype.h> <fset.h> <pmset.h>
+ $omake zzdebug.x <error.h> <imhdr.h> <ctype.h> <fset.h> <pmset.h>
+ $link zzdebug.o zzinterp.o -o zzdebug.e
+ ;
+
+libex.a:
+ # Retranslate any recently modified generic sources.
+ $ifeq (hostid, unix)
+ $call tfiles
+ $endif
+
+ # Transfer <plset.h> dependency to <pmset.h>.
+ $ifnewer (<plset.h>, <pmset.h>)
+ $copy <pmset.h> temp.pm
+ $move temp.pm <pmset.h>
+ $endif
+
+ @tf # Update datatype expanded files.
+
+ mioclose.x mio.h <pmset.h>
+ mioopen.x mio.h <pmset.h>
+ mioopeno.x mio.h <imhdr.h> <pmset.h>
+ mioseti.x mio.h <pmset.h>
+ miosrange.x mio.h <imhdr.h>
+ miostati.x mio.h <pmset.h>
+ pmaccess.x pmio.com <plio.h> <pmset.h>
+ pmascii.x pmio.com <plio.h> <pmset.h>
+ pmbox.x pmio.com <plio.h> <pmset.h>
+ pmcircle.x pmio.com <plio.h> <pmset.h>
+ pmclear.x pmio.com <imhdr.h> <plio.h> <pmset.h>
+ pmempty.x pmio.com <imhdr.h> <plio.h> <pmset.h>
+ pmglls.x pmio.com <imhdr.h> <plio.h> <pmset.h>
+ pmline.x pmio.com <plio.h> <pmset.h>
+ pmlinene.x pmio.com <plio.h> <imhdr.h> <pmset.h>
+ pmnewmask.x <imhdr.h> <imio.h> <plio.h> <pmset.h>
+ pmplls.x pmio.com <plio.h> <pmset.h>
+ pmpoint.x pmio.com <plio.h> <pmset.h>
+ pmpolygon.x pmio.com <plio.h> <pmset.h>
+ pmrio.x pmio.com <plio.h> <pmset.h>
+ pmrop.x pmio.com <plio.h> <imhdr.h> <pmset.h>
+ pmsectnc.x pmio.com <plio.h> <pmset.h>
+ pmsectne.x pmio.com <plio.h> <pmset.h>
+ pmseti.x <imio.h> <plio.h> <pmset.h>
+ pmstati.x <imio.h> <plio.h> <pmset.h>
+ pmsplane.x pmio.com <plio.h> <pmset.h>
+ pmsten.x pmio.com <plio.h> <imhdr.h> <pmset.h>
+ ;
diff --git a/sys/pmio/plprop.gx b/sys/pmio/plprop.gx
new file mode 100644
index 00000000..60d1c603
--- /dev/null
+++ b/sys/pmio/plprop.gx
@@ -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_pixrop$t (px_src,xs,src_maxval, px_dst,ds,dst_maxval, npix, rop)
+
+PIXEL 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
+PIXEL 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
+PIXEL 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 aclr$t (px_dst[ds], npix)
+ return
+ case PIX_SET:
+ call amovk$t (data, px_dst[ds], npix)
+ goto out_
+ case PIX_SRC:
+ if (src_maxval != 1)
+ call amov$t (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_PIXEL)
+
+ do i = 1, npix
+ if (px_src[xs+i-1] > 0)
+ Mem$t[src+i-1] = src_value
+ else
+ Mem$t[src+i-1] = 0
+
+ switch (opcode) {
+ case PIX_NOTSRC:
+ do i = 1, npix
+ px_dst[ds+i-1] = not (Mem$t[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 (Mem$t[src+i-1], px_dst[ds+i-1])
+ case PIX_SRC_OR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = or (Mem$t[src+i-1], px_dst[ds+i-1])
+ case PIX_SRC_XOR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = xor (Mem$t[src+i-1], px_dst[ds+i-1])
+
+ case PIX_SRC_AND_NOTDST:
+ do i = 1, npix
+ px_dst[ds+i-1] = and (Mem$t[src+i-1], not(px_dst[ds+i-1]))
+ case PIX_SRC_OR_NOTDST:
+ do i = 1, npix
+ px_dst[ds+i-1] = or (Mem$t[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(Mem$t[src+i-1]), px_dst[ds+i-1])
+ case PIX_NOTSRC_OR_DST:
+ do i = 1, npix
+ px_dst[ds+i-1] = or (not(Mem$t[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 (Mem$t[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 (Mem$t[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 (Mem$t[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 argt$t (px_dst[ds], npix, ceil, data)
+ } else if (dst_maxval > 1) {
+ data = dst_maxval
+ call aandk$t (px_dst[ds], data, px_dst[ds], npix)
+ }
+end
diff --git a/sys/pmio/pmaccess.x b/sys/pmio/pmaccess.x
new file mode 100644
index 00000000..74f73e72
--- /dev/null
+++ b/sys/pmio/pmaccess.x
@@ -0,0 +1,24 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <plio.h>
+
+# PM_ACCESS -- Return a pointer (type short) to the indicated mask image
+# line. A valid pointer is always returned; if the mask line is empty, the
+# pointer will reference the "empty line" linelist.
+
+pointer procedure pm_access (pl, v)
+
+pointer pl #I mask descriptor
+long v[PM_MAXDIM] #I coordinates of desired line
+
+pointer pl_access()
+include "pmio.com"
+
+begin
+ if (PM_MAPXY(pl) == YES) {
+ call imaplv (PM_REFIM(pl), v, v1, PM_MAXDIM)
+ return (pl_access (pl, v1))
+ } else
+ return (pl_access (pl, v))
+end
diff --git a/sys/pmio/pmascii.x b/sys/pmio/pmascii.x
new file mode 100644
index 00000000..3e85d0af
--- /dev/null
+++ b/sys/pmio/pmascii.x
@@ -0,0 +1,27 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <plio.h>
+
+# PM_ASCIIDUMP -- Dump a two dimensional region of a mask as a printable ASCII
+# character array on the output stream. Intended as a simple debugging tool;
+# see also PM_SAVEIM.
+
+procedure pm_asciidump (pl, vs, ve, outfd)
+
+pointer pl #I mask descriptor
+long vs[ARB] #I ll vector (only first two elements used)
+long ve[ARB] #I ur vector (only first two elements used)
+int outfd #I output file
+
+include "pmio.com"
+
+begin
+ if (PM_MAPXY(pl) == NO)
+ call pl_asciidump (pl, vs, ve, outfd)
+ else {
+ call imaplv (PM_REFIM(pl), vs, v1, PM_MAXDIM)
+ call imaplv (PM_REFIM(pl), ve, v2, PM_MAXDIM)
+ call pl_asciidump (pl, v1, v2, outfd)
+ }
+end
diff --git a/sys/pmio/pmbox.x b/sys/pmio/pmbox.x
new file mode 100644
index 00000000..d54eb8fa
--- /dev/null
+++ b/sys/pmio/pmbox.x
@@ -0,0 +1,34 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <plio.h>
+
+# PM_BOX -- Rasterop between a box as source, and an existing mask as dest.
+# This is a 2-dim operator. The pm_setplane procedure is used to specify
+# the plane to be modified.
+
+procedure pm_box (pl, x1,y1, x2,y2, rop)
+
+pointer pl #I mask descriptor
+int x1,y1 #I lower left corner of box
+int x2,y2 #I upper right corner of box
+int rop #I rasterop
+
+errchk pl_getplane
+include "pmio.com"
+
+begin
+ if (PM_MAPXY(pl) == YES) {
+ call pl_getplane (pl, v1)
+ v1[1] = x1; v1[2] = y1
+ call imaplv (PM_REFIM(pl), v1, v2, PM_MAXDIM)
+
+ call pl_getplane (pl, v3)
+ v3[1] = x2; v3[2] = y2
+ call imaplv (PM_REFIM(pl), v3, v4, PM_MAXDIM)
+
+ call pl_box (pl, v2[1],v2[2], v4[1],v4[2], rop)
+
+ } else
+ call pl_box (pl, x1,y1, x2,y2, rop)
+end
diff --git a/sys/pmio/pmcircle.x b/sys/pmio/pmcircle.x
new file mode 100644
index 00000000..086da99a
--- /dev/null
+++ b/sys/pmio/pmcircle.x
@@ -0,0 +1,37 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <plio.h>
+
+# PM_CIRCLE -- Rasterop between a circular region as source, and an existing
+# mask as destination. It is not necessary for the center of the circle to
+# be inside the mask; if it is outside, the boundary of the circle will be
+# clipped to the boundary of the mask. This is a 2-dim operator. If the
+# image dimensionality is greater than two the pm_setplane procedure should
+# be called first to specify the plane to be modified.
+
+procedure pm_circle (pl, x, y, radius, rop)
+
+pointer pl #I mask descriptor
+int x,y #I center coords of circle
+int radius #I radius of circle
+int rop #I rasterop
+
+errchk pl_getplane
+include "pmio.com"
+
+begin
+ if (PM_MAPXY(pl) == YES) {
+ call pl_getplane (pl, v1)
+ v1[1] = x; v1[2] = y
+ call imaplv (PM_REFIM(pl), v1, v2, PM_MAXDIM)
+
+ call pl_getplane (pl, v3)
+ v3[1] = x + radius; v3[2] = y
+ call imaplv (PM_REFIM(pl), v3, v4, PM_MAXDIM)
+
+ call pl_circle (pl, v2[1], v2[2], abs(v4[1]-v2[1]), rop)
+
+ } else
+ call pl_circle (pl, x, y, radius, rop)
+end
diff --git a/sys/pmio/pmclear.x b/sys/pmio/pmclear.x
new file mode 100644
index 00000000..1aed4013
--- /dev/null
+++ b/sys/pmio/pmclear.x
@@ -0,0 +1,28 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include <plio.h>
+
+# PM_CLEAR -- Clear a mask. The entire surface is cleared. This is equivalent
+# to a full surface pm_rop with rop=PIX_CLR, but is more convenient and can be
+# implemented more efficiently since the entire surface is cleared.
+
+procedure pm_clear (pl)
+
+pointer pl #I mask descriptor
+
+include "pmio.com"
+
+begin
+ if (PM_MAPXY(pl) == YES) {
+ call amovkl (1, v1, PM_MAXDIM)
+ call imaplv (PM_REFIM(pl), v1, v2, PM_MAXDIM)
+ call amovl (IM_LEN(PM_REFIM(pl),1), v3, PM_MAXDIM)
+ call imaplv (PM_REFIM(pl), v3, v4, PM_MAXDIM)
+
+ call pl_rop (NULL, NULL, pl, v2, v4, PIX_CLR)
+
+ } else
+ call pl_clear (pl)
+end
diff --git a/sys/pmio/pmempty.x b/sys/pmio/pmempty.x
new file mode 100644
index 00000000..c8797663
--- /dev/null
+++ b/sys/pmio/pmempty.x
@@ -0,0 +1,27 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include <plio.h>
+
+# PM_EMPTY -- Test whether a mask is empty, i.e., contains no nonzero pixels.
+
+bool procedure pm_empty (pl)
+
+pointer pl #I mask descriptor
+
+bool pl_empty(), pl_sectnotempty()
+include "pmio.com"
+
+begin
+ if (PM_MAPXY(pl) == YES) {
+ call amovkl (1, v1, PM_MAXDIM)
+ call imaplv (PM_REFIM(pl), v1, v2, PM_MAXDIM)
+ call amovl (IM_LEN(PM_REFIM(pl),1), v3, PM_MAXDIM)
+ call imaplv (PM_REFIM(pl), v3, v4, PM_MAXDIM)
+
+ return (!pl_sectnotempty (pl, v2, v4, PM_MAXDIM))
+
+ } else
+ return (pl_empty (pl))
+end
diff --git a/sys/pmio/pmglls.x b/sys/pmio/pmglls.x
new file mode 100644
index 00000000..6604c999
--- /dev/null
+++ b/sys/pmio/pmglls.x
@@ -0,0 +1,78 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include <plio.h>
+
+# PM_GLLS -- Get a line segment as a list list, applying the given ROP to
+# combine the pixels with those of the output line list.
+
+procedure pm_glls (pl, v, ll_dst, ll_depth, npix, rop)
+
+pointer pl #I mask descriptor
+long v[PL_MAXDIM] #I vector coords of line segment
+short ll_dst[ARB] #O output line list
+int ll_depth #I line list depth, bits
+int npix #I number of pixels desired
+int rop #I rasterop
+
+int ll_len, temp, np, step, xstep
+pointer sp, px_src, ll_src, ll_out, im
+int pl_p2li()
+include "pmio.com"
+
+begin
+ im = PM_REFIM(pl)
+ if (PM_MAPXY(pl) == NO) {
+ call pl_glls (pl, v, ll_dst, ll_depth, npix, rop)
+ return
+ }
+
+ call smark (sp)
+ call salloc (ll_src, LL_MAXLEN(pl), TY_SHORT)
+
+ # Determine physical coords of line segment.
+ call amovl (v, v3, PM_MAXDIM)
+ call imaplv (im, v3, v1, PM_MAXDIM)
+ v3[1] = v3[1] + npix - 1
+ call imaplv (im, v3, v2, PM_MAXDIM)
+
+ # Get line scaling parameters.
+ if (npix <= 1)
+ xstep = 1
+ else
+ xstep = (v2[1] - v1[1]) / (npix - 1)
+ step = xstep
+ if (xstep < 0) {
+ temp = v1[1]; v1[1] = v2[1]; v2[1] = temp
+ step = -step
+ }
+
+ # Extract the pixels.
+ np = (npix - 1) * step + 1
+ call salloc (px_src, np, TY_INT)
+ call pl_glpi (pl, v1, Memi[px_src], 0, np, PIX_SRC)
+
+ # Subsample and flip if necessary.
+ if (step > 1)
+ call imsamp (Memi[px_src], Memi[px_src], npix, SZ_INT, step)
+ if (xstep < 0)
+ call imaflp (Memi[px_src], npix, SZ_INT)
+
+ # Convert to a line list.
+ ll_len = pl_p2li (Memi[px_src], 1, Mems[ll_src], npix)
+
+ # Copy to or combine with destination.
+ if (!R_NEED_DST(rop)) {
+ ll_len = LP_LEN(ll_src)
+ call amovs (Mems[ll_src], ll_dst, ll_len)
+ } else {
+ call salloc (ll_out, LL_MAXLEN(pl), TY_SHORT)
+ call pl_linerop (Mems[ll_src], 1, PL_MAXVAL(pl), ll_dst, 1,
+ MV(ll_depth), Mems[ll_out], npix, rop)
+ ll_len = LP_LEN(ll_out)
+ call amovs (Mems[ll_out], ll_dst, ll_len)
+ }
+
+ call sfree (sp)
+end
diff --git a/sys/pmio/pmglp.gx b/sys/pmio/pmglp.gx
new file mode 100644
index 00000000..26c6b2e0
--- /dev/null
+++ b/sys/pmio/pmglp.gx
@@ -0,0 +1,69 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <plio.h>
+
+# PM_GLP -- Get a line segment as a pixel array, applying the given ROP to
+# combine the pixels with those of the output array.
+
+procedure pm_glp$t (pl, v, px_dst, px_depth, npix, rop)
+
+pointer pl #I mask descriptor
+long v[PL_MAXDIM] #I vector coords of line segment
+PIXEL 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 temp, np, step, xstep
+pointer sp, px_src, px_out, im
+include "../pmio.com"
+
+begin
+ im = PM_REFIM(pl)
+ if (PM_MAPXY(pl) == NO) {
+ call pl_glp$t (pl, v, px_dst, px_depth, npix, rop)
+ return
+ }
+
+ call smark (sp)
+
+ # Determine physical coords of line segment.
+ call amovl (v, v3, PM_MAXDIM)
+ call imaplv (im, v3, v1, PM_MAXDIM)
+ v3[1] = v3[1] + npix - 1
+ call imaplv (im, v3, v2, PM_MAXDIM)
+
+ # Get line scaling parameters.
+ if (npix <= 1)
+ xstep = 1
+ else
+ xstep = (v2[1] - v1[1]) / (npix - 1)
+ step = xstep
+ if (xstep < 0) {
+ temp = v1[1]; v1[1] = v2[1]; v2[1] = temp
+ step = -step
+ }
+
+ # Extract the pixels.
+ np = (npix - 1) * step + 1
+ call salloc (px_src, np, TY_PIXEL)
+ call pl_glp$t (pl, v1, Mem$t[px_src], 0, np, PIX_SRC)
+
+ # Subsample and flip if necessary.
+ if (step > 1)
+ call imsamp (Mem$t[px_src], Mem$t[px_src], npix, SZ_PIXEL, step)
+ if (xstep < 0)
+ call imaflp (Mem$t[px_src], npix, SZ_PIXEL)
+
+ if (!R_NEED_DST(rop))
+ call amov$t (Mem$t[px_src], px_dst, npix)
+ else {
+ call salloc (px_out, npix, TY_PIXEL)
+ call pl_pixrop$t (Mem$t[px_src], 1, PL_MAXVAL(pl), px_dst, 1,
+ MV(px_depth), npix, rop)
+ call amov$t (Mem$t[px_out], px_dst, npix)
+ }
+
+ call sfree (sp)
+end
diff --git a/sys/pmio/pmglr.gx b/sys/pmio/pmglr.gx
new file mode 100644
index 00000000..9c2e2606
--- /dev/null
+++ b/sys/pmio/pmglr.gx
@@ -0,0 +1,85 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include <plio.h>
+
+# PM_GLR -- Get a line segment as a range list, applying the given ROP to
+# combine the pixels with those of the output line list. Note that this
+# operator uses IMIO if a section transformation is needed, hence if the
+# application also uses IMIO to directly access the mask image, care must
+# be taken to avoid confusion over the use of IMIO allocated pixel buffers.
+
+procedure pm_glr$t (pl, v, rl_dst, rl_depth, npix, rop)
+
+pointer pl #I mask descriptor
+long v[PL_MAXDIM] #I vector coords of line segment
+PIXEL rl_dst[3,ARB] #O output line list
+int rl_depth #I line list depth, bits
+int npix #I number of pixels desired
+int rop #I rasterop
+
+int rl_len, temp, step, xstep, np
+pointer sp, px_src, rl_src, rl_out, im
+include "../pmio.com"
+int pl_p2r$t()
+
+begin
+ im = PM_REFIM(pl)
+ if (PM_MAPXY(pl) == NO) {
+ call pl_glr$t (pl, v, rl_dst, rl_depth, npix, rop)
+ return
+ }
+
+ call smark (sp)
+ call salloc (rl_src, RL_MAXLEN(pl), TY_PIXEL)
+
+ # Determine physical coords of line segment.
+ call amovl (v, v3, PM_MAXDIM)
+ call imaplv (im, v3, v1, PM_MAXDIM)
+ v3[1] = v3[1] + npix - 1
+ call imaplv (im, v3, v2, PM_MAXDIM)
+
+ # Get line scaling parameters.
+ if (npix <= 1)
+ xstep = 1
+ else
+ xstep = (v2[1] - v1[1]) / (npix - 1)
+ step = xstep
+ if (xstep < 0) {
+ temp = v1[1]; v1[1] = v2[1]; v2[1] = temp
+ step = -step
+ }
+
+ # Extract the pixels.
+ np = (npix - 1) * step + 1
+ call salloc (px_src, np, TY_PIXEL)
+ call pl_glp$t (pl, v1, Mem$t[px_src], 0, np, PIX_SRC)
+
+ # Subsample and flip if necessary.
+ if (step > 1)
+ call imsamp (Mem$t[px_src], Mem$t[px_src], npix, SZ_PIXEL, step)
+ if (xstep < 0)
+ call imaflp (Mem$t[px_src], npix, SZ_PIXEL)
+
+ # Convert to a range list.
+ rl_len = pl_p2r$t (Mem$t[px_src], 1, Mem$t[rl_src], npix)
+
+ # Copy to or combine with destination.
+ if (!R_NEED_DST(rop)) {
+ rl_len = RLI_LEN(rl_src) * RL_LENELEM
+ call amov$t (Mem$t[rl_src], rl_dst, rl_len)
+ } else {
+ call salloc (rl_out, RL_MAXLEN(pl), TY_PIXEL)
+ call pl_rangerop$t (Mem$t[rl_src], 1, PL_MAXVAL(pl), rl_dst, 1,
+ MV(rl_depth), Mem$t[rl_out], npix, rop)
+ $if (datatype == s)
+ rl_len = RLS_LEN(rl_out) * RL_LENELEM
+ $else
+ rl_len = RLI_LEN(rl_out) * RL_LENELEM
+ $endif
+ call amov$t (Mem$t[rl_out], rl_dst, rl_len)
+ }
+
+ call sfree (sp)
+end
diff --git a/sys/pmio/pmio.com b/sys/pmio/pmio.com
new file mode 100644
index 00000000..76616e6a
--- /dev/null
+++ b/sys/pmio/pmio.com
@@ -0,0 +1,5 @@
+# PMIO.COM -- A few scratch vectors used in many of the PMIO routines,
+# defined in common to save some space.
+
+long v1[PM_MAXDIM], v2[PM_MAXDIM], v3[PM_MAXDIM], v4[PM_MAXDIM]
+common /pmiocom/ v1, v2, v3, v4
diff --git a/sys/pmio/pmline.x b/sys/pmio/pmline.x
new file mode 100644
index 00000000..36be1cb4
--- /dev/null
+++ b/sys/pmio/pmline.x
@@ -0,0 +1,36 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <plio.h>
+
+# PM_LINE -- Perform a rasterop operation upon a line of arbitrary width drawn
+# at an arbitrary orientation in a 2-dimensional plane of a mask. If the
+# dimensionality of the mask exceeds 2, the pm_setplane() procedure should be
+# called first to define the plane of the mask to be modified.
+
+procedure pm_line (pl, x1, y1, x2, y2, width, rop)
+
+pointer pl #I mask descriptor
+int x1,y1 #I start point of line
+int x2,y2 #I end point of line
+int width #I width of line to be drawn, pixels
+int rop #I rasterop defining operation
+
+errchk pl_getplane
+include "pmio.com"
+
+begin
+ if (PM_MAPXY(pl) == YES) {
+ call pl_getplane (pl, v1)
+ v1[1] = x1; v1[2] = y1
+ call imaplv (PM_REFIM(pl), v1, v2, PM_MAXDIM)
+
+ call pl_getplane (pl, v3)
+ v3[1] = x2; v3[2] = y2
+ call imaplv (PM_REFIM(pl), v3, v4, PM_MAXDIM)
+
+ call pl_line (pl, v2[1],v2[2], v4[1],v4[2], width, rop)
+
+ } else
+ call pl_line (pl, x1, y1, x2, y2, width, rop)
+end
diff --git a/sys/pmio/pmlinene.x b/sys/pmio/pmlinene.x
new file mode 100644
index 00000000..0e49de54
--- /dev/null
+++ b/sys/pmio/pmlinene.x
@@ -0,0 +1,28 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include <plio.h>
+
+# PM_LINENOTEMPTY -- Test whether the indicated mask image line is empty.
+
+bool procedure pm_linenotempty (pl, v)
+
+pointer pl #I mask descriptor
+long v[PM_MAXDIM] #I coordinates of desired line
+
+bool pl_sectnotempty(), pl_linenotempty()
+include "pmio.com"
+
+begin
+ if (PM_MAPXY(pl) == YES) {
+ call imaplv (PM_REFIM(pl), v, v1, PM_MAXDIM)
+ call amovl (v, v2, PM_MAXDIM)
+ v2[1] = IM_LEN(PM_REFIM(pl),1)
+ call imaplv (PM_REFIM(pl), v2, v3, PM_MAXDIM)
+
+ return (pl_sectnotempty (pl, v1, v3, PM_MAXDIM))
+
+ } else
+ return (pl_linenotempty (pl, v))
+end
diff --git a/sys/pmio/pmnewmask.x b/sys/pmio/pmnewmask.x
new file mode 100644
index 00000000..200e4841
--- /dev/null
+++ b/sys/pmio/pmnewmask.x
@@ -0,0 +1,28 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <imhdr.h>
+include <imio.h>
+include <plio.h>
+
+# PM_NEWMASK -- Create an empty mask with the same dimensionality and size as
+# the given reference image.
+
+pointer procedure pm_newmask (ref_im, depth)
+
+pointer ref_im #I reference image
+int depth #I mask depth, bits
+
+pointer pl
+pointer pl_open()
+errchk pl_open
+
+begin
+ pl = pl_open (NULL)
+ call pl_ssize (pl, IM_NDIM(ref_im), IM_SVLEN(ref_im,1), depth)
+
+ PM_REFIM(pl) = ref_im
+ PM_MAPXY(pl) = IM_SECTUSED(ref_im)
+
+ return (pl)
+end
diff --git a/sys/pmio/pmplls.x b/sys/pmio/pmplls.x
new file mode 100644
index 00000000..b7f0e826
--- /dev/null
+++ b/sys/pmio/pmplls.x
@@ -0,0 +1,103 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <plio.h>
+
+# PM_PLLS -- Put a line segment input as a list list to a mask, applying the
+# given ROP to combine the pixels with those of the output mask.
+
+procedure pm_plls (pl, v, ll_raw, ll_depth, npix, rop)
+
+pointer pl #I mask descriptor
+long v[PL_MAXDIM] #I vector coords of line segment
+short ll_raw[ARB] #I input line list
+int ll_depth #I line list depth, bits
+int npix #I number of pixels affected
+int rop #I rasterop
+
+pointer sp, ll_src, ll_dst, ll_stn, ll_out, px_src, im
+int ll_len, step, xstep, temp, np, ip, i
+int pl_l2pi(), pl_p2li()
+pointer pl_access()
+include "pmio.com"
+
+begin
+ im = PM_REFIM(pl)
+ if (PM_MAPXY(pl) == NO) {
+ call pl_plls (pl, v, ll_raw, ll_depth, npix, rop)
+ return
+ }
+
+ call smark (sp)
+ call salloc (ll_src, LL_MAXLEN(pl), TY_SHORT)
+
+ # Determine physical coords of line segment.
+ call amovl (v, v3, PM_MAXDIM)
+ call imaplv (im, v3, v1, PM_MAXDIM)
+ v3[1] = v3[1] + npix - 1
+ call imaplv (im, v3, v2, PM_MAXDIM)
+
+ # Get line scaling parameters.
+ if (npix <= 1)
+ xstep = 1
+ else
+ xstep = (v2[1] - v1[1]) / (npix - 1)
+ step = xstep
+ if (xstep < 0) {
+ temp = v1[1]; v1[1] = v2[1]; v2[1] = temp
+ step = -step
+ }
+
+ np = (npix - 1) * step + 1
+ ll_stn = NULL
+
+ # Resample and flip the line list if necessary. Construct a stencil
+ # list if the step size is greater than 1.
+
+ if (xstep < 0 || step > 1) {
+ call salloc (px_src, np, TY_INT)
+ i = pl_l2pi (ll_raw, 1, Memi[px_src], npix)
+ call aclri (Memi[px_src+i], np - i)
+
+ # Flip data array.
+ if (xstep < 0)
+ call imaflp (Memi[px_src], npix, SZ_INT)
+
+ if (step > 1) {
+ # Resample data array.
+ ip = px_src + npix - 1
+ do i = np, 1, -step {
+ Memi[px_src+i-1] = Memi[ip]
+ ip = ip - 1
+ }
+
+ # Construct stencil.
+ call salloc (ll_stn, LL_MAXLEN(pl), TY_SHORT)
+ call aclri (Memi[px_src], np)
+ do i = 1, np, step
+ Memi[px_src+i-1] = 1
+ ll_len = pl_p2li (Memi[px_src], 1, Mems[ll_stn], np)
+ }
+
+ # Convert flipped and resampled data back to line list.
+ ll_len = pl_p2li (Memi[px_src], 1, Mems[ll_src], np)
+
+ } else {
+ ll_len = LL_LEN(ll_raw)
+ call amovs (ll_raw, Mems[ll_src], ll_len)
+ }
+
+ # Copy to or combine with destination.
+ if (ll_stn == NULL)
+ call pl_plls (pl, v1, Mems[ll_src], ll_depth, np, rop)
+ else {
+ call salloc (ll_out, LL_MAXLEN(pl), TY_SHORT)
+ ll_dst = pl_access (pl, v1)
+ call pl_linestencil (Mems[ll_src], 1, MV(ll_depth),
+ Mems[ll_dst], v1, PL_MAXVAL(pl), Mems[ll_stn], 1,
+ Mems[ll_out], np, rop)
+ call pl_update (pl, v1, Mems[ll_out])
+ }
+
+ call sfree (sp)
+end
diff --git a/sys/pmio/pmplp.gx b/sys/pmio/pmplp.gx
new file mode 100644
index 00000000..90246ddc
--- /dev/null
+++ b/sys/pmio/pmplp.gx
@@ -0,0 +1,34 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <plio.h>
+
+# PM_PLP -- Put a line segment input as a pixel array a mask, applying the
+# given ROP to combine the pixels with those of the mask.
+
+procedure pm_plp$t (pl, v, px_src, px_depth, npix, rop)
+
+pointer pl #I mask descriptor
+long v[PL_MAXDIM] #I vector coords of line segment
+PIXEL px_src[ARB] #I input pixel array
+int px_depth #I pixel depth, bits
+int npix #I number of pixels affected
+int rop #I rasterop
+
+pointer sp, ll_src
+int ll_len, pl_p2l$t()
+include "../pmio.com"
+
+begin
+ if (PM_MAPXY(pl) == NO)
+ call pl_plp$t (pl, v, px_src, px_depth, npix, rop)
+ else {
+ call smark (sp)
+ call salloc (ll_src, LL_MAXLEN(pl), TY_SHORT)
+
+ ll_len = pl_p2l$t (px_src, 1, Mems[ll_src], npix)
+ call pm_plls (pl, v, Mems[ll_src], px_depth, npix, rop)
+
+ call sfree (sp)
+ }
+end
diff --git a/sys/pmio/pmplr.gx b/sys/pmio/pmplr.gx
new file mode 100644
index 00000000..6f87601b
--- /dev/null
+++ b/sys/pmio/pmplr.gx
@@ -0,0 +1,34 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <plio.h>
+
+# PM_PLR -- Put a line segment input as a range list to a mask, applying the
+# given ROP to combine the pixels with those of the output mask.
+
+procedure pm_plr$t (pl, v, rl_src, rl_depth, npix, rop)
+
+pointer pl #I mask descriptor
+long v[PL_MAXDIM] #I vector coords of line segment
+PIXEL rl_src[3,ARB] #I input range list
+int rl_depth #I range list pixel depth, bits
+int npix #I number of pixels affected
+int rop #I rasterop
+
+pointer sp, ll_src
+int ll_len, pl_r2l$t()
+include "../pmio.com"
+
+begin
+ if (PM_MAPXY(pl) == NO)
+ call pl_plr$t (pl, v, rl_src, rl_depth, npix, rop)
+ else {
+ call smark (sp)
+ call salloc (ll_src, LL_MAXLEN(pl), TY_SHORT)
+
+ ll_len = pl_r2l$t (rl_src, 1, Mems[ll_src], npix)
+ call pm_plls (pl, v, Mems[ll_src], rl_depth, npix, rop)
+
+ call sfree (sp)
+ }
+end
diff --git a/sys/pmio/pmpoint.x b/sys/pmio/pmpoint.x
new file mode 100644
index 00000000..c464c47e
--- /dev/null
+++ b/sys/pmio/pmpoint.x
@@ -0,0 +1,31 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <plio.h>
+
+# PM_POINT -- Perform a rasterop operation on a single point in a line of a
+# 2-dimensional plane of a mask. If the dimensionality of the mask exceeds 2,
+# the pm_setplane() procedure should be called first to define the plane of
+# the mask to be modified.
+
+procedure pm_point (pl, x, y, rop)
+
+pointer pl #I mask descriptor
+int x #I pixel to be modified
+int y #I line to be modified
+int rop #I rasterop defining operation
+
+errchk pl_getplane
+include "pmio.com"
+
+begin
+ if (PM_MAPXY(pl) == YES) {
+ call pl_getplane (pl, v1)
+ v1[1] = x; v1[2] = y
+ call imaplv (PM_REFIM(pl), v1, v2, PM_MAXDIM)
+
+ call pl_point (pl, v2[1], v2[2], rop)
+
+ } else
+ call pl_point (pl, x, y, rop)
+end
diff --git a/sys/pmio/pmpolygon.x b/sys/pmio/pmpolygon.x
new file mode 100644
index 00000000..5e09e5b7
--- /dev/null
+++ b/sys/pmio/pmpolygon.x
@@ -0,0 +1,42 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <plio.h>
+
+# PM_POLYGON -- Perform a rasterop operation on the area enclosed by a polygon
+# drawn in a 2-dimensional plane of a mask. If the dimensionality of the mask
+# exceeds 2, the pm_setplane() procedure should be called first to define the
+# plane of the mask to be modified.
+
+procedure pm_polygon (pl, x, y, npts, rop)
+
+pointer pl #I mask descriptor
+int x[npts] #I polygon x-vertices
+int y[npts] #I polygon y-vertices
+int npts #I number of points in polygon
+int rop #I rasterop defining operation
+
+int i
+pointer sp, xp, yp
+errchk pl_getplane
+include "pmio.com"
+
+begin
+ if (PM_MAPXY(pl) == YES) {
+ call smark (sp)
+ call salloc (xp, npts, TY_INT)
+ call salloc (yp, npts, TY_INT)
+
+ call pl_getplane (pl, v1)
+ do i = 1, npts {
+ v1[1] = x[i]; v1[2] = y[i]
+ call imaplv (PM_REFIM(pl), v1, v2, PM_MAXDIM)
+ Memi[xp+i-1] = v2[1]; Memi[yp+i-1] = v2[2]
+ }
+
+ call pl_polygon (pl, Memi[xp], Memi[yp], npts, rop)
+ call sfree (sp)
+
+ } else
+ call pl_polygon (pl, x, y, npts, rop)
+end
diff --git a/sys/pmio/pmrio.x b/sys/pmio/pmrio.x
new file mode 100644
index 00000000..278c7f30
--- /dev/null
+++ b/sys/pmio/pmrio.x
@@ -0,0 +1,128 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <plio.h>
+
+.help PMRIO
+.nf ---------------------------------------------------------------------------
+PMRIO -- A small package used to provide a means for efficient random
+sampling (at the pixel level) of large PMIO masks. In other words, if we have
+a large mask and want to determine the values of successive mask pixels at
+random locations in the mask, this package provides a more efficient means
+for doing so than calling a routine such as PM_GLPI. The mask must already
+exist; means are not provided within this package for creating or editing
+masks, only for reading them.
+
+ pmr = pmr_open (pm, plane, buflimit)
+ pmr_setrect (pmr, x1,y1, x2,y2)
+ mval = pmr_getpix (pmr, x, y)
+ pmr_close (pmr)
+
+PMR_OPEN opens the indicated 2 dimensional plane of the N dimensional mask PM.
+Buffer space used to provide an efficient means of randomly sampling the mask
+will be kept to within approximately BUFLIMIT integer units of storage (the
+internal table used to sample the mask is type integer, so BUFLIMIT is the
+approximate number of entries in the table). Random sampling of the mask is
+provided by the integer function PMR_GETPIX, which returns the mask value at
+the point [i,j] within the specified plane. PMR_SETRECT may be called before
+calling PMR_GETPIX to set the clipping rectangle, which defaults to the
+boundaries of the mask. If a PMR_GETPIX call references outside the clipping
+region, ERR will be returned as the mask value (normal mask values are >= 0).
+Use of a clipping region other than the boundaries of the full mask can avoid
+the need for redundant clipping operations in the client. PMR_CLOSE should
+be called to free the PMRIO table space (which can be extensive) when no longer
+needed.
+
+This package is a front end to the PLRIO package in PLIO, which does all the
+real work.
+.endhelp ----------------------------------------------------------------------
+
+# The following definitions must agree with those in plio$plrio.x.
+define PMR_PL Memi[$1] # backpointer to PLIO descriptor
+define PMR_PLANE Memi[$1+10+($2)-1] # defines 2D plane in ND mask
+
+
+# PMR_OPEN -- Open a PMIO mask for random pixel access. Provides efficient
+# random pixel level access to any size mask. This is a 2-dimensional
+# operator, but can be used to sample any 2-dim plane of an N-dim mask.
+
+pointer procedure pmr_open (pl, plane, buflimit)
+
+pointer pl #I PMIO/PLIO descriptor
+int plane[ARB] #I 2-dim plane to be accessed
+int buflimit #I approximate table size, or 0 if don't care
+
+pointer plr_open()
+include "pmio.com"
+
+begin
+ if (PM_MAPXY(pl) == YES) {
+ call imaplv (PM_REFIM(pl), plane, v1, PM_MAXDIM)
+ return (plr_open (pl, v1, buflimit))
+ } else
+ return (plr_open (pl, plane, buflimit))
+end
+
+
+# PMR_GETPIX -- Return the value of the given mask pixel, identified by the
+# 2-dim coordinates of the pixel relative to the plane of the N-dim mask
+# specified at open time.
+
+int procedure pmr_getpix (pmr, i, j)
+
+pointer pmr #I PMR descriptor
+int i, j #I plane-relative coordinates of pixel
+
+pointer pl
+int plr_getpix()
+include "pmio.com"
+
+begin
+ pl = PMR_PL(pmr)
+ if (PM_MAPXY(pl) == YES) {
+ PMR_PLANE(pmr,1) = i
+ PMR_PLANE(pmr,2) = j
+ call imaplv (PM_REFIM(pl), PMR_PLANE(pmr,1), v1, PM_MAXDIM)
+ return (plr_getpix (pmr, v1[1], v1[2]))
+ } else
+ return (plr_getpix (pmr, i, j))
+end
+
+
+# PMR_SETRECT -- Set the clipping region for PMR_GETPIX.
+
+procedure pmr_setrect (pmr, x1,y1, x2,y2)
+
+pointer pmr #I PMR descriptor
+int x1,y1 #I lower left corner of region
+int x2,y2 #I upper right corner of region
+
+pointer pl
+include "pmio.com"
+
+begin
+ pl = PMR_PL(pmr)
+ if (PM_MAPXY(pl) == YES) {
+ call amovi (PMR_PLANE(pmr,1), v1, PM_MAXDIM)
+ v1[1] = x1; v1[2] = y1
+ call imaplv (PM_REFIM(pl), v1, v2, PM_MAXDIM)
+
+ call amovi (PMR_PLANE(pmr,1), v3, PM_MAXDIM)
+ v3[1] = x2; v3[2] = y2
+ call imaplv (PM_REFIM(pl), v3, v4, PM_MAXDIM)
+
+ call plr_setrect (pmr, v2[1],v2[2], v4[1],v4[2])
+ } else
+ call plr_setrect (pmr, x1,y1, x2,y2)
+end
+
+
+# PMR_CLOSE -- Free a PMRIO descriptor.
+
+procedure pmr_close (pmr)
+
+pointer pmr #I PMR descriptor
+
+begin
+ call plr_close (pmr)
+end
diff --git a/sys/pmio/pmrop.x b/sys/pmio/pmrop.x
new file mode 100644
index 00000000..ddd77d37
--- /dev/null
+++ b/sys/pmio/pmrop.x
@@ -0,0 +1,74 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include <plio.h>
+
+# PM_ROP -- Perform a rasterop operation from the source mask to the
+# destination mask at the given offsets. The source and destination need
+# not be the same size or dimensionality, but out of bounds references are
+# not permitted. If the source is of lesser dimensionality than the
+# indicated section of the destination, then the source will be rewound
+# and reread as necessary to operate upon the entire destination subregion,
+# e.g., a line source mask may be applied to successive lines of a plane,
+# or a plane mask may be applied to successive planes of a 3D mask.
+# The source and destination masks may be the same if desired, but if the
+# source and destination regions overlap feedback may occur (this could be
+# fixed). With some rasterops, e.g, PIX_SET or PIX_CLR, no source mask is
+# required, and pm_src=NULL is permitted.
+
+procedure pm_rop (pm_src, vs_src, pm_dst, vs_dst, vn, rop)
+
+pointer pm_src #I source mask or NULL
+long vs_src[PM_MAXDIM] #I start vector in source mask
+pointer pm_dst #I destination mask (required)
+long vs_dst[PM_MAXDIM] #I start vector in destination mask
+long vn[PM_MAXDIM] #I vector giving subregion size
+long rop #I rasterop
+
+int i
+include "pmio.com"
+
+begin
+ # If an image section is used on either the source or destination
+ # mask, map the input vectors into the physical image space and
+ # perform the rasterop operation there.
+
+ if (PM_MAPXY(pm_src) == YES || PM_MAPXY(pm_dst) == YES) {
+ # Compute V1, the start vector in the source mask.
+ call imaplv (PM_REFIM(pm_src), vs_src, v1, PM_MAXDIM)
+
+ # Compute V3, the end vector in the source mask.
+ call aaddl (vs_src, vn, v2, PM_MAXDIM)
+ call asubkl (v2, 1, v2, PL_MAXDIM)
+ call aminl (v2, IM_LEN(PM_REFIM(pm_src),1), v2, PM_MAXDIM)
+ call imaplv (PM_REFIM(pm_src), v2, v3, PM_MAXDIM)
+
+ # Swap V1 and V3 if necessary.
+ call aminl (v1, v3, v1, PM_MAXDIM)
+
+ # Compute V2, the start vector in the destination mask.
+ call imaplv (PM_REFIM(pm_dst), vs_dst, v2, PM_MAXDIM)
+
+ # Compute V4, the end vector in the destination mask.
+ call aaddl (vs_dst, vn, v3, PM_MAXDIM)
+ call asubkl (v3, 1, v3, PL_MAXDIM)
+ call aminl (v3, IM_LEN(PM_REFIM(pm_dst),1), v3, PM_MAXDIM)
+ call imaplv (PM_REFIM(pm_dst), v3, v4, PM_MAXDIM)
+
+ # Compute v3 = vn for rasterop. Input: SRC=v1:v3, DST=v2:v4
+ # This also swaps v2 and v4 if necessary.
+
+ do i = 1, PM_MAXDIM
+ if (v2[i] > v4[i]) {
+ v3[i] = v2[i] - v4[i] + 1
+ v2[i] = v4[i]
+ } else
+ v3[i] = v4[i] - v2[i] + 1
+
+ # Perform the rasterop.
+ call pl_rop (pm_src, v1, pm_dst, v2, v3, rop)
+
+ } else
+ call pl_rop (pm_src, vs_src, pm_dst, vs_dst, vn, rop)
+end
diff --git a/sys/pmio/pmsectnc.x b/sys/pmio/pmsectnc.x
new file mode 100644
index 00000000..ce424c3e
--- /dev/null
+++ b/sys/pmio/pmsectnc.x
@@ -0,0 +1,35 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <plio.h>
+
+# PM_SECTNOTCONST -- Test whether the indicated mask image section is constant,
+# i.e., all the mask pixels therein are set to the same value. If so, return
+# the mask value as an output argument.
+
+bool procedure pm_sectnotconst (pl, vs, ve, ndim, mval)
+
+pointer pl #I mask descriptor
+long vs[PM_MAXDIM] #I starting coordinates of section
+long ve[PM_MAXDIM] #I ending coordinates of section
+int ndim #I dimension of section
+int mval #O mask value
+
+bool pl_sectnotconst()
+include "pmio.com"
+
+begin
+ if (PM_MAPXY(pl) == YES) {
+ call amovkl ( 1, v1, PM_MAXDIM)
+ call amovl (vs, v1, ndim)
+ call imaplv (PM_REFIM(pl), v1, v2, PM_MAXDIM)
+
+ call amovkl ( 1, v3, PM_MAXDIM)
+ call amovl (ve, v3, ndim)
+ call imaplv (PM_REFIM(pl), v3, v4, PM_MAXDIM)
+
+ return (pl_sectnotconst (pl, v2, v4, PM_MAXDIM, mval))
+
+ } else
+ return (pl_sectnotconst (pl, vs, ve, ndim, mval))
+end
diff --git a/sys/pmio/pmsectne.x b/sys/pmio/pmsectne.x
new file mode 100644
index 00000000..654c53b1
--- /dev/null
+++ b/sys/pmio/pmsectne.x
@@ -0,0 +1,32 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <plio.h>
+
+# PM_SECTNOTEMPTY -- Test whether the indicated mask image section is empty.
+
+bool procedure pm_sectnotempty (pl, vs, ve, ndim)
+
+pointer pl #I mask descriptor
+long vs[PM_MAXDIM] #I starting coordinates of section
+long ve[PM_MAXDIM] #I ending coordinates of section
+int ndim
+
+bool pl_sectnotempty()
+include "pmio.com"
+
+begin
+ if (PM_MAPXY(pl) == YES) {
+ call amovkl ( 1, v1, PM_MAXDIM)
+ call amovl (vs, v1, ndim)
+ call imaplv (PM_REFIM(pl), v1, v2, PM_MAXDIM)
+
+ call amovkl ( 1, v3, PM_MAXDIM)
+ call amovl (ve, v3, ndim)
+ call imaplv (PM_REFIM(pl), v3, v4, PM_MAXDIM)
+
+ return (pl_sectnotempty (pl, v2, v4, PM_MAXDIM))
+
+ } else
+ return (pl_sectnotempty (pl, vs, ve, ndim))
+end
diff --git a/sys/pmio/pmseti.x b/sys/pmio/pmseti.x
new file mode 100644
index 00000000..ef1fd99e
--- /dev/null
+++ b/sys/pmio/pmseti.x
@@ -0,0 +1,30 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <syserr.h>
+include <pmset.h>
+include <plio.h>
+include <imio.h>
+
+# PM_SETI -- Set a PMIO or PLIO parameter.
+
+procedure pm_seti (pl, param, value)
+
+pointer pl #I mask descriptor
+int param #I parameter code
+int value #I parameter value
+
+begin
+ switch (param) {
+ case P_REFIM:
+ PM_REFIM(pl) = value
+ PM_MAPXY(pl) = IM_SECTUSED(value)
+ case P_MAPXY:
+ PM_MAPXY(pl) = value
+ case P_MAXLINE:
+ PL_MAXLINE(pl) = value
+ case P_DEPTH:
+ PL_MAXVAL(pl) = MV(value)
+ default:
+ call syserr (SYS_PLINVPAR)
+ }
+end
diff --git a/sys/pmio/pmsplane.x b/sys/pmio/pmsplane.x
new file mode 100644
index 00000000..4fcad1fd
--- /dev/null
+++ b/sys/pmio/pmsplane.x
@@ -0,0 +1,22 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <plio.h>
+
+# PM_SETPLANE -- Set the 2-Dim plane to be referenced in calls to the pm_box,
+# pm_circle, etc. geometric region masking operators.
+
+procedure pm_setplane (pl, v)
+
+pointer pl #I mask descriptor
+long v[ARB] #I vector defining plane
+
+include "pmio.com"
+
+begin
+ if (PM_MAPXY(pl) == YES) {
+ call imaplv (PM_REFIM(pl), v, v1, PM_MAXDIM)
+ call pl_setplane (pl, v1)
+ } else
+ call pl_setplane (pl, v)
+end
diff --git a/sys/pmio/pmstati.x b/sys/pmio/pmstati.x
new file mode 100644
index 00000000..4e8566d2
--- /dev/null
+++ b/sys/pmio/pmstati.x
@@ -0,0 +1,32 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <syserr.h>
+include <pmset.h>
+include <plio.h>
+include <imio.h>
+
+# PM_STATI -- Stat a PMIO or PLIO parameter.
+
+int procedure pm_stati (pl, param)
+
+pointer pl #I mask descriptor
+int param #I parameter code
+
+int i
+
+begin
+ switch (param) {
+ case P_REFIM:
+ return (PM_REFIM(pl))
+ case P_MAPXY:
+ return (PM_MAPXY(pl))
+ case P_MAXLINE:
+ return (PL_MAXLINE(pl))
+ case P_DEPTH:
+ do i = 0, ARB
+ if (2**i > min (I_PVMAX, PL_MAXVAL(pl)))
+ return (i)
+ default:
+ call syserr (SYS_PLINVPAR)
+ }
+end
diff --git a/sys/pmio/pmsten.x b/sys/pmio/pmsten.x
new file mode 100644
index 00000000..09a34a52
--- /dev/null
+++ b/sys/pmio/pmsten.x
@@ -0,0 +1,77 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include <plio.h>
+
+# PM_STENCIL -- Perform a rasterop operation from the source mask to the
+# destination mask at the given offsets, but only within the regions set to
+# one in the stencil mask.
+
+procedure pm_stencil (pm_src, vs_src, pm_dst, vs_dst, pm_stn, vs_stn, vn, rop)
+
+pointer pm_src #I source mask or NULL
+long vs_src[PM_MAXDIM] #I start vector in source mask
+pointer pm_dst #I destination mask (required)
+long vs_dst[PM_MAXDIM] #I start vector in destination mask
+pointer pm_stn #I stencil mask (required)
+long vs_stn[PM_MAXDIM] #I start vector in stencil mask
+long vn[PM_MAXDIM] #I vector giving subregion size
+long rop #I rasterop
+
+int i
+long v5[PM_MAXDIM], v6[PM_MAXDIM]
+include "pmio.com"
+
+begin
+ # If an image section is in use on any of the input mask operands,
+ # perform a coordination transformation into physical mask space
+ # before performing the stencil operation.
+
+ if (PM_MAPXY(pm_src) == YES || PM_MAPXY(pm_dst) == YES ||
+ PM_MAPXY(pm_stn) == YES) {
+
+ # Compute the geometry V1:V3 of the source mask.
+ call imaplv (PM_REFIM(pm_src), vs_src, v1, PM_MAXDIM)
+
+ call aaddl (vs_src, vn, v2, PM_MAXDIM)
+ call asubkl (v2, 1, v2, PM_MAXDIM)
+ call aminl (v2, IM_LEN(PM_REFIM(pm_src),1), v2, PM_MAXDIM)
+ call imaplv (PM_REFIM(pm_src), v2, v3, PM_MAXDIM)
+
+ # Swap V1 and V3 if necessary.
+ call aminl (v1, v3, v1, PM_MAXDIM)
+
+ # Compute the geometry V2:V4 of the destination mask.
+ call imaplv (PM_REFIM(pm_dst), vs_dst, v2, PM_MAXDIM)
+
+ call aaddl (vs_dst, vn, v3, PM_MAXDIM)
+ call asubkl (v3, 1, v3, PM_MAXDIM)
+ call aminl (v3, IM_LEN(PM_REFIM(pm_dst),1), v3, PM_MAXDIM)
+ call imaplv (PM_REFIM(pm_dst), v3, v4, PM_MAXDIM)
+
+ # Compute v3 = vn for rasterop. Input: SRC=v1:v3, DST=v2:v4
+ # This also swaps v2 and v4 if necessary.
+
+ do i = 1, PM_MAXDIM
+ if (v2[i] > v4[i]) {
+ v3[i] = v2[i] - v4[i] + 1
+ v2[i] = v4[i]
+ } else
+ v3[i] = v4[i] - v2[i] + 1
+
+ # Compute the start vector V4 of the stencil mask.
+ call imaplv (PM_REFIM(pm_stn), vs_stn, v4, PM_MAXDIM)
+ call aaddl (vs_stn, vn, v5, PM_MAXDIM)
+ call asubkl (v5, 1, v5, PM_MAXDIM)
+ call aminl (v5, IM_LEN(PM_REFIM(pm_stn),1), v5, PM_MAXDIM)
+ call imaplv (PM_REFIM(pm_stn), v5, v6, PM_MAXDIM)
+ call aminl (v4, v6, v4, PM_MAXDIM)
+
+ # Perform the rasterop operation.
+ call pl_stencil (pm_src, v1, pm_dst, v2, pm_stn, v4, v3, rop)
+
+ } else
+ call pl_stencil (pm_src, vs_src, pm_dst, vs_dst,
+ pm_stn, vs_stn, vn, rop)
+end
diff --git a/sys/pmio/tf/miogld.x b/sys/pmio/tf/miogld.x
new file mode 100644
index 00000000..7c3dc743
--- /dev/null
+++ b/sys/pmio/tf/miogld.x
@@ -0,0 +1,103 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include <plio.h>
+include "../mio.h"
+
+# MIO_GLSEG -- Get a line segment from a masked image. A line segment is a
+# region of the data image for which the corresponding region of the mask has
+# the constant nonzero value MVAL. Line segments are returned for each line in
+# the region VS to VE, returning the number of pixels in each line segment as
+# the function value, or EOF when the region is exhausted. Once EOF is
+# reached, repeated calls will continue to return EOF until the next call to
+# MIO_SETRANGE. Repeated calls to MIO_SETRANGE may be used to access a series
+# of distinct regions in the image. If a subregion of the image is being
+# accessed with MIO_SETRANGE, the vector coordinates V returned below will
+# be relative to the defined subregion (if this is not what is desired,
+# the range should be set to the full image and a region mask used to mask
+# off the subregion to be accessed).
+
+int procedure mio_glsegd (mp, ptr, mval, v, npix)
+
+pointer mp #I MIO descriptor
+pointer ptr #O pointer to a buffer containing the data
+int mval #O mask value for the output line segment
+long v[IM_MAXDIM] #U coords of first pixel in output ine segment
+int npix #O number of pixels in output line segment
+
+int x1, i
+long ve[IM_MAXDIM]
+pointer pm, im, rl, rp, bp
+pointer imgl2d(), imgl3d(), imggsd()
+errchk imgl2d, imgl3d, imggsd, pm_glri
+bool pm_sectnotempty()
+int plloop()
+
+begin
+ pm = M_PM(mp)
+ rl = M_RLP(mp)
+
+ # Initialization performed for the first i/o on a new region.
+ if (M_ACTIVE(mp) == NO) {
+ call plsslv (pm, M_VS(mp,1), M_VN(mp,1), M_V(mp,1), M_VE(mp,1))
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ M_ACTIVE(mp) = YES
+ }
+
+ # Get a new mask line?
+ while (M_RLI(mp) > RLI_LEN(rl))
+ if (plloop (M_V(mp,1), M_VS(mp,1), M_VE(mp,1),
+ M_NDIM(mp)) == LOOP_DONE) {
+ return (EOF)
+ } else {
+ call amovl (M_V(mp,1), ve, M_NDIM(mp))
+ ve[1] = M_VE(mp,1)
+ if (pm_sectnotempty (pm, M_V(mp,1), ve, M_NDIM(mp))) {
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ }
+ }
+
+ # Get a new image line?
+ if (M_RLI(mp) == RL_FIRST) {
+ call amovl (M_V(mp,1), v, M_NDIM(mp))
+ im = M_IM(mp)
+
+ if (M_LINEIO(mp) == YES && M_NDIM(mp) == 2)
+ bp = imgl2d (im, v[2])
+ else if (M_LINEIO(mp) == YES && M_NDIM(mp) == 3)
+ bp = imgl3d (im, v[2], v[3])
+ else {
+ call amovl (v, ve, M_NDIM(mp)); ve[1] = M_VE(mp,1)
+ bp = imggsd (im, v, ve, M_NDIM(mp))
+ }
+
+ M_LBP(mp) = bp
+ } else
+ bp = M_LBP(mp)
+
+ # Return the next line segment.
+ rp = rl + (M_RLI(mp) - 1) * RL_LENELEM
+ M_RLI(mp) = M_RLI(mp) + 1
+
+ x1 = Memi[rp+RL_XOFF]
+ npix = Memi[rp+RL_NOFF]
+ mval = Memi[rp+RL_VOFF]
+ ptr = bp + x1 - M_VS(mp,1)
+
+ if (M_REGCOORDS(mp) == NO) {
+ v[1] = x1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i)
+ } else {
+ v[1] = x1 - M_VS(mp,1) + 1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i) - M_VS(mp,i) + 1
+ }
+
+ return (npix)
+end
diff --git a/sys/pmio/tf/miogli.x b/sys/pmio/tf/miogli.x
new file mode 100644
index 00000000..726f46f1
--- /dev/null
+++ b/sys/pmio/tf/miogli.x
@@ -0,0 +1,103 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include <plio.h>
+include "../mio.h"
+
+# MIO_GLSEG -- Get a line segment from a masked image. A line segment is a
+# region of the data image for which the corresponding region of the mask has
+# the constant nonzero value MVAL. Line segments are returned for each line in
+# the region VS to VE, returning the number of pixels in each line segment as
+# the function value, or EOF when the region is exhausted. Once EOF is
+# reached, repeated calls will continue to return EOF until the next call to
+# MIO_SETRANGE. Repeated calls to MIO_SETRANGE may be used to access a series
+# of distinct regions in the image. If a subregion of the image is being
+# accessed with MIO_SETRANGE, the vector coordinates V returned below will
+# be relative to the defined subregion (if this is not what is desired,
+# the range should be set to the full image and a region mask used to mask
+# off the subregion to be accessed).
+
+int procedure mio_glsegi (mp, ptr, mval, v, npix)
+
+pointer mp #I MIO descriptor
+pointer ptr #O pointer to a buffer containing the data
+int mval #O mask value for the output line segment
+long v[IM_MAXDIM] #U coords of first pixel in output ine segment
+int npix #O number of pixels in output line segment
+
+int x1, i
+long ve[IM_MAXDIM]
+pointer pm, im, rl, rp, bp
+pointer imgl2i(), imgl3i(), imggsi()
+errchk imgl2i, imgl3i, imggsi, pm_glri
+bool pm_sectnotempty()
+int plloop()
+
+begin
+ pm = M_PM(mp)
+ rl = M_RLP(mp)
+
+ # Initialization performed for the first i/o on a new region.
+ if (M_ACTIVE(mp) == NO) {
+ call plsslv (pm, M_VS(mp,1), M_VN(mp,1), M_V(mp,1), M_VE(mp,1))
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ M_ACTIVE(mp) = YES
+ }
+
+ # Get a new mask line?
+ while (M_RLI(mp) > RLI_LEN(rl))
+ if (plloop (M_V(mp,1), M_VS(mp,1), M_VE(mp,1),
+ M_NDIM(mp)) == LOOP_DONE) {
+ return (EOF)
+ } else {
+ call amovl (M_V(mp,1), ve, M_NDIM(mp))
+ ve[1] = M_VE(mp,1)
+ if (pm_sectnotempty (pm, M_V(mp,1), ve, M_NDIM(mp))) {
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ }
+ }
+
+ # Get a new image line?
+ if (M_RLI(mp) == RL_FIRST) {
+ call amovl (M_V(mp,1), v, M_NDIM(mp))
+ im = M_IM(mp)
+
+ if (M_LINEIO(mp) == YES && M_NDIM(mp) == 2)
+ bp = imgl2i (im, v[2])
+ else if (M_LINEIO(mp) == YES && M_NDIM(mp) == 3)
+ bp = imgl3i (im, v[2], v[3])
+ else {
+ call amovl (v, ve, M_NDIM(mp)); ve[1] = M_VE(mp,1)
+ bp = imggsi (im, v, ve, M_NDIM(mp))
+ }
+
+ M_LBP(mp) = bp
+ } else
+ bp = M_LBP(mp)
+
+ # Return the next line segment.
+ rp = rl + (M_RLI(mp) - 1) * RL_LENELEM
+ M_RLI(mp) = M_RLI(mp) + 1
+
+ x1 = Memi[rp+RL_XOFF]
+ npix = Memi[rp+RL_NOFF]
+ mval = Memi[rp+RL_VOFF]
+ ptr = bp + x1 - M_VS(mp,1)
+
+ if (M_REGCOORDS(mp) == NO) {
+ v[1] = x1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i)
+ } else {
+ v[1] = x1 - M_VS(mp,1) + 1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i) - M_VS(mp,i) + 1
+ }
+
+ return (npix)
+end
diff --git a/sys/pmio/tf/miogll.x b/sys/pmio/tf/miogll.x
new file mode 100644
index 00000000..6566ae01
--- /dev/null
+++ b/sys/pmio/tf/miogll.x
@@ -0,0 +1,103 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include <plio.h>
+include "../mio.h"
+
+# MIO_GLSEG -- Get a line segment from a masked image. A line segment is a
+# region of the data image for which the corresponding region of the mask has
+# the constant nonzero value MVAL. Line segments are returned for each line in
+# the region VS to VE, returning the number of pixels in each line segment as
+# the function value, or EOF when the region is exhausted. Once EOF is
+# reached, repeated calls will continue to return EOF until the next call to
+# MIO_SETRANGE. Repeated calls to MIO_SETRANGE may be used to access a series
+# of distinct regions in the image. If a subregion of the image is being
+# accessed with MIO_SETRANGE, the vector coordinates V returned below will
+# be relative to the defined subregion (if this is not what is desired,
+# the range should be set to the full image and a region mask used to mask
+# off the subregion to be accessed).
+
+int procedure mio_glsegl (mp, ptr, mval, v, npix)
+
+pointer mp #I MIO descriptor
+pointer ptr #O pointer to a buffer containing the data
+int mval #O mask value for the output line segment
+long v[IM_MAXDIM] #U coords of first pixel in output ine segment
+int npix #O number of pixels in output line segment
+
+int x1, i
+long ve[IM_MAXDIM]
+pointer pm, im, rl, rp, bp
+pointer imgl2l(), imgl3l(), imggsl()
+errchk imgl2l, imgl3l, imggsl, pm_glri
+bool pm_sectnotempty()
+int plloop()
+
+begin
+ pm = M_PM(mp)
+ rl = M_RLP(mp)
+
+ # Initialization performed for the first i/o on a new region.
+ if (M_ACTIVE(mp) == NO) {
+ call plsslv (pm, M_VS(mp,1), M_VN(mp,1), M_V(mp,1), M_VE(mp,1))
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ M_ACTIVE(mp) = YES
+ }
+
+ # Get a new mask line?
+ while (M_RLI(mp) > RLI_LEN(rl))
+ if (plloop (M_V(mp,1), M_VS(mp,1), M_VE(mp,1),
+ M_NDIM(mp)) == LOOP_DONE) {
+ return (EOF)
+ } else {
+ call amovl (M_V(mp,1), ve, M_NDIM(mp))
+ ve[1] = M_VE(mp,1)
+ if (pm_sectnotempty (pm, M_V(mp,1), ve, M_NDIM(mp))) {
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ }
+ }
+
+ # Get a new image line?
+ if (M_RLI(mp) == RL_FIRST) {
+ call amovl (M_V(mp,1), v, M_NDIM(mp))
+ im = M_IM(mp)
+
+ if (M_LINEIO(mp) == YES && M_NDIM(mp) == 2)
+ bp = imgl2l (im, v[2])
+ else if (M_LINEIO(mp) == YES && M_NDIM(mp) == 3)
+ bp = imgl3l (im, v[2], v[3])
+ else {
+ call amovl (v, ve, M_NDIM(mp)); ve[1] = M_VE(mp,1)
+ bp = imggsl (im, v, ve, M_NDIM(mp))
+ }
+
+ M_LBP(mp) = bp
+ } else
+ bp = M_LBP(mp)
+
+ # Return the next line segment.
+ rp = rl + (M_RLI(mp) - 1) * RL_LENELEM
+ M_RLI(mp) = M_RLI(mp) + 1
+
+ x1 = Memi[rp+RL_XOFF]
+ npix = Memi[rp+RL_NOFF]
+ mval = Memi[rp+RL_VOFF]
+ ptr = bp + x1 - M_VS(mp,1)
+
+ if (M_REGCOORDS(mp) == NO) {
+ v[1] = x1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i)
+ } else {
+ v[1] = x1 - M_VS(mp,1) + 1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i) - M_VS(mp,i) + 1
+ }
+
+ return (npix)
+end
diff --git a/sys/pmio/tf/mioglr.x b/sys/pmio/tf/mioglr.x
new file mode 100644
index 00000000..d0fa8de0
--- /dev/null
+++ b/sys/pmio/tf/mioglr.x
@@ -0,0 +1,103 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include <plio.h>
+include "../mio.h"
+
+# MIO_GLSEG -- Get a line segment from a masked image. A line segment is a
+# region of the data image for which the corresponding region of the mask has
+# the constant nonzero value MVAL. Line segments are returned for each line in
+# the region VS to VE, returning the number of pixels in each line segment as
+# the function value, or EOF when the region is exhausted. Once EOF is
+# reached, repeated calls will continue to return EOF until the next call to
+# MIO_SETRANGE. Repeated calls to MIO_SETRANGE may be used to access a series
+# of distinct regions in the image. If a subregion of the image is being
+# accessed with MIO_SETRANGE, the vector coordinates V returned below will
+# be relative to the defined subregion (if this is not what is desired,
+# the range should be set to the full image and a region mask used to mask
+# off the subregion to be accessed).
+
+int procedure mio_glsegr (mp, ptr, mval, v, npix)
+
+pointer mp #I MIO descriptor
+pointer ptr #O pointer to a buffer containing the data
+int mval #O mask value for the output line segment
+long v[IM_MAXDIM] #U coords of first pixel in output ine segment
+int npix #O number of pixels in output line segment
+
+int x1, i
+long ve[IM_MAXDIM]
+pointer pm, im, rl, rp, bp
+pointer imgl2r(), imgl3r(), imggsr()
+errchk imgl2r, imgl3r, imggsr, pm_glri
+bool pm_sectnotempty()
+int plloop()
+
+begin
+ pm = M_PM(mp)
+ rl = M_RLP(mp)
+
+ # Initialization performed for the first i/o on a new region.
+ if (M_ACTIVE(mp) == NO) {
+ call plsslv (pm, M_VS(mp,1), M_VN(mp,1), M_V(mp,1), M_VE(mp,1))
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ M_ACTIVE(mp) = YES
+ }
+
+ # Get a new mask line?
+ while (M_RLI(mp) > RLI_LEN(rl))
+ if (plloop (M_V(mp,1), M_VS(mp,1), M_VE(mp,1),
+ M_NDIM(mp)) == LOOP_DONE) {
+ return (EOF)
+ } else {
+ call amovl (M_V(mp,1), ve, M_NDIM(mp))
+ ve[1] = M_VE(mp,1)
+ if (pm_sectnotempty (pm, M_V(mp,1), ve, M_NDIM(mp))) {
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ }
+ }
+
+ # Get a new image line?
+ if (M_RLI(mp) == RL_FIRST) {
+ call amovl (M_V(mp,1), v, M_NDIM(mp))
+ im = M_IM(mp)
+
+ if (M_LINEIO(mp) == YES && M_NDIM(mp) == 2)
+ bp = imgl2r (im, v[2])
+ else if (M_LINEIO(mp) == YES && M_NDIM(mp) == 3)
+ bp = imgl3r (im, v[2], v[3])
+ else {
+ call amovl (v, ve, M_NDIM(mp)); ve[1] = M_VE(mp,1)
+ bp = imggsr (im, v, ve, M_NDIM(mp))
+ }
+
+ M_LBP(mp) = bp
+ } else
+ bp = M_LBP(mp)
+
+ # Return the next line segment.
+ rp = rl + (M_RLI(mp) - 1) * RL_LENELEM
+ M_RLI(mp) = M_RLI(mp) + 1
+
+ x1 = Memi[rp+RL_XOFF]
+ npix = Memi[rp+RL_NOFF]
+ mval = Memi[rp+RL_VOFF]
+ ptr = bp + x1 - M_VS(mp,1)
+
+ if (M_REGCOORDS(mp) == NO) {
+ v[1] = x1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i)
+ } else {
+ v[1] = x1 - M_VS(mp,1) + 1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i) - M_VS(mp,i) + 1
+ }
+
+ return (npix)
+end
diff --git a/sys/pmio/tf/miogls.x b/sys/pmio/tf/miogls.x
new file mode 100644
index 00000000..4973da4f
--- /dev/null
+++ b/sys/pmio/tf/miogls.x
@@ -0,0 +1,103 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include <plio.h>
+include "../mio.h"
+
+# MIO_GLSEG -- Get a line segment from a masked image. A line segment is a
+# region of the data image for which the corresponding region of the mask has
+# the constant nonzero value MVAL. Line segments are returned for each line in
+# the region VS to VE, returning the number of pixels in each line segment as
+# the function value, or EOF when the region is exhausted. Once EOF is
+# reached, repeated calls will continue to return EOF until the next call to
+# MIO_SETRANGE. Repeated calls to MIO_SETRANGE may be used to access a series
+# of distinct regions in the image. If a subregion of the image is being
+# accessed with MIO_SETRANGE, the vector coordinates V returned below will
+# be relative to the defined subregion (if this is not what is desired,
+# the range should be set to the full image and a region mask used to mask
+# off the subregion to be accessed).
+
+int procedure mio_glsegs (mp, ptr, mval, v, npix)
+
+pointer mp #I MIO descriptor
+pointer ptr #O pointer to a buffer containing the data
+int mval #O mask value for the output line segment
+long v[IM_MAXDIM] #U coords of first pixel in output ine segment
+int npix #O number of pixels in output line segment
+
+int x1, i
+long ve[IM_MAXDIM]
+pointer pm, im, rl, rp, bp
+pointer imgl2s(), imgl3s(), imggss()
+errchk imgl2s, imgl3s, imggss, pm_glri
+bool pm_sectnotempty()
+int plloop()
+
+begin
+ pm = M_PM(mp)
+ rl = M_RLP(mp)
+
+ # Initialization performed for the first i/o on a new region.
+ if (M_ACTIVE(mp) == NO) {
+ call plsslv (pm, M_VS(mp,1), M_VN(mp,1), M_V(mp,1), M_VE(mp,1))
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ M_ACTIVE(mp) = YES
+ }
+
+ # Get a new mask line?
+ while (M_RLI(mp) > RLI_LEN(rl))
+ if (plloop (M_V(mp,1), M_VS(mp,1), M_VE(mp,1),
+ M_NDIM(mp)) == LOOP_DONE) {
+ return (EOF)
+ } else {
+ call amovl (M_V(mp,1), ve, M_NDIM(mp))
+ ve[1] = M_VE(mp,1)
+ if (pm_sectnotempty (pm, M_V(mp,1), ve, M_NDIM(mp))) {
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ }
+ }
+
+ # Get a new image line?
+ if (M_RLI(mp) == RL_FIRST) {
+ call amovl (M_V(mp,1), v, M_NDIM(mp))
+ im = M_IM(mp)
+
+ if (M_LINEIO(mp) == YES && M_NDIM(mp) == 2)
+ bp = imgl2s (im, v[2])
+ else if (M_LINEIO(mp) == YES && M_NDIM(mp) == 3)
+ bp = imgl3s (im, v[2], v[3])
+ else {
+ call amovl (v, ve, M_NDIM(mp)); ve[1] = M_VE(mp,1)
+ bp = imggss (im, v, ve, M_NDIM(mp))
+ }
+
+ M_LBP(mp) = bp
+ } else
+ bp = M_LBP(mp)
+
+ # Return the next line segment.
+ rp = rl + (M_RLI(mp) - 1) * RL_LENELEM
+ M_RLI(mp) = M_RLI(mp) + 1
+
+ x1 = Memi[rp+RL_XOFF]
+ npix = Memi[rp+RL_NOFF]
+ mval = Memi[rp+RL_VOFF]
+ ptr = bp + x1 - M_VS(mp,1)
+
+ if (M_REGCOORDS(mp) == NO) {
+ v[1] = x1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i)
+ } else {
+ v[1] = x1 - M_VS(mp,1) + 1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i) - M_VS(mp,i) + 1
+ }
+
+ return (npix)
+end
diff --git a/sys/pmio/tf/mioglx.x b/sys/pmio/tf/mioglx.x
new file mode 100644
index 00000000..44f866a2
--- /dev/null
+++ b/sys/pmio/tf/mioglx.x
@@ -0,0 +1,103 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include <plio.h>
+include "../mio.h"
+
+# MIO_GLSEG -- Get a line segment from a masked image. A line segment is a
+# region of the data image for which the corresponding region of the mask has
+# the constant nonzero value MVAL. Line segments are returned for each line in
+# the region VS to VE, returning the number of pixels in each line segment as
+# the function value, or EOF when the region is exhausted. Once EOF is
+# reached, repeated calls will continue to return EOF until the next call to
+# MIO_SETRANGE. Repeated calls to MIO_SETRANGE may be used to access a series
+# of distinct regions in the image. If a subregion of the image is being
+# accessed with MIO_SETRANGE, the vector coordinates V returned below will
+# be relative to the defined subregion (if this is not what is desired,
+# the range should be set to the full image and a region mask used to mask
+# off the subregion to be accessed).
+
+int procedure mio_glsegx (mp, ptr, mval, v, npix)
+
+pointer mp #I MIO descriptor
+pointer ptr #O pointer to a buffer containing the data
+int mval #O mask value for the output line segment
+long v[IM_MAXDIM] #U coords of first pixel in output ine segment
+int npix #O number of pixels in output line segment
+
+int x1, i
+long ve[IM_MAXDIM]
+pointer pm, im, rl, rp, bp
+pointer imgl2x(), imgl3x(), imggsx()
+errchk imgl2x, imgl3x, imggsx, pm_glri
+bool pm_sectnotempty()
+int plloop()
+
+begin
+ pm = M_PM(mp)
+ rl = M_RLP(mp)
+
+ # Initialization performed for the first i/o on a new region.
+ if (M_ACTIVE(mp) == NO) {
+ call plsslv (pm, M_VS(mp,1), M_VN(mp,1), M_V(mp,1), M_VE(mp,1))
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ M_ACTIVE(mp) = YES
+ }
+
+ # Get a new mask line?
+ while (M_RLI(mp) > RLI_LEN(rl))
+ if (plloop (M_V(mp,1), M_VS(mp,1), M_VE(mp,1),
+ M_NDIM(mp)) == LOOP_DONE) {
+ return (EOF)
+ } else {
+ call amovl (M_V(mp,1), ve, M_NDIM(mp))
+ ve[1] = M_VE(mp,1)
+ if (pm_sectnotempty (pm, M_V(mp,1), ve, M_NDIM(mp))) {
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ }
+ }
+
+ # Get a new image line?
+ if (M_RLI(mp) == RL_FIRST) {
+ call amovl (M_V(mp,1), v, M_NDIM(mp))
+ im = M_IM(mp)
+
+ if (M_LINEIO(mp) == YES && M_NDIM(mp) == 2)
+ bp = imgl2x (im, v[2])
+ else if (M_LINEIO(mp) == YES && M_NDIM(mp) == 3)
+ bp = imgl3x (im, v[2], v[3])
+ else {
+ call amovl (v, ve, M_NDIM(mp)); ve[1] = M_VE(mp,1)
+ bp = imggsx (im, v, ve, M_NDIM(mp))
+ }
+
+ M_LBP(mp) = bp
+ } else
+ bp = M_LBP(mp)
+
+ # Return the next line segment.
+ rp = rl + (M_RLI(mp) - 1) * RL_LENELEM
+ M_RLI(mp) = M_RLI(mp) + 1
+
+ x1 = Memi[rp+RL_XOFF]
+ npix = Memi[rp+RL_NOFF]
+ mval = Memi[rp+RL_VOFF]
+ ptr = bp + x1 - M_VS(mp,1)
+
+ if (M_REGCOORDS(mp) == NO) {
+ v[1] = x1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i)
+ } else {
+ v[1] = x1 - M_VS(mp,1) + 1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i) - M_VS(mp,i) + 1
+ }
+
+ return (npix)
+end
diff --git a/sys/pmio/tf/miopld.x b/sys/pmio/tf/miopld.x
new file mode 100644
index 00000000..33515220
--- /dev/null
+++ b/sys/pmio/tf/miopld.x
@@ -0,0 +1,102 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include <plio.h>
+include "../mio.h"
+
+# MIO_PLSEG -- Put a line segment to a masked image. A line segment is a
+# region of the data image for which the corresponding region of the mask has
+# the constant nonzero value MVAL. Line segments are returned for each line in
+# the region VS to VE, returning the number of pixels in each line segment as
+# the function value, or EOF when the region is exhausted. Once EOF is
+# reached, repeated calls will continue to return EOF until the next call to
+# MIO_SETRANGE. Repeated calls to MIO_SETRANGE may be used to access a series
+# of distinct regions in the image. If a subregion of the image is being
+# accessed with MIO_SETRANGE, the vector coordinates V returned below will
+# be relative to the defined subregion (if this is not what is desired,
+# the range should be set to the full image and a region mask used to mask
+# off the subregion to be accessed).
+
+int procedure mio_plsegd (mp, ptr, mval, v, npix)
+
+pointer mp #I MIO descriptor
+pointer ptr #O pointer to a buffer containing the data
+int mval #O mask value for the output line segment
+long v[IM_MAXDIM] #U vector coordinates of first pixel
+int npix #O number of pixels in output line segment
+
+int x1, i
+long ve[IM_MAXDIM]
+pointer pm, im, rl, rp, bp
+pointer impl2d(), impl3d(), impgsd()
+errchk impl2d, impl3d, impgsd, pm_glri
+bool pm_sectnotempty()
+int plloop()
+
+begin
+ pm = M_PM(mp)
+ rl = M_RLP(mp)
+
+ # Initialization performed for the first i/o on a new region.
+ if (M_ACTIVE(mp) == NO) {
+ call plsslv (pm, M_VS(mp,1), M_VN(mp,1), M_V(mp,1), M_VE(mp,1))
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ M_ACTIVE(mp) = YES
+ }
+
+ # Get a new mask line?
+ while (M_RLI(mp) > RLI_LEN(rl))
+ if (plloop (M_V(mp,1), M_VS(mp,1), M_VE(mp,1),
+ M_NDIM(mp)) == LOOP_DONE) {
+ return (EOF)
+ } else {
+ call amovl (M_V(mp,1), ve, M_NDIM(mp))
+ ve[1] = M_VE(mp,1)
+ if (pm_sectnotempty (pm, M_V(mp,1), ve, M_NDIM(mp))) {
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ }
+ }
+
+
+ # Get a new image line?
+ if (M_RLI(mp) == RL_FIRST) {
+ call amovl (M_V(mp,1), v, IM_MAXDIM)
+ im = M_IM(mp)
+
+ if (M_LINEIO(mp) == YES && M_NDIM(mp) == 2)
+ bp = impl2d (im, v[2])
+ else if (M_LINEIO(mp) == YES && M_NDIM(mp) == 3)
+ bp = impl3d (im, v[2], v[3])
+ else
+ bp = impgsd (im, v, ve, M_NDIM(mp))
+
+ M_LBP(mp) = bp
+ } else
+ bp = M_LBP(mp)
+
+ # Return the next line segment.
+ rp = rl + (M_RLI(mp) - 1) * RL_LENELEM
+ M_RLI(mp) = M_RLI(mp) + 1
+
+ x1 = Memi[rp+RL_XOFF]
+ npix = Memi[rp+RL_NOFF]
+ mval = Memi[rp+RL_VOFF]
+ ptr = bp + x1 - M_VS(mp,1)
+
+ if (M_REGCOORDS(mp) == NO) {
+ v[1] = x1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i)
+ } else {
+ v[1] = x1 - M_VS(mp,1) + 1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i) - M_VS(mp,i) + 1
+ }
+
+ return (npix)
+end
diff --git a/sys/pmio/tf/miopli.x b/sys/pmio/tf/miopli.x
new file mode 100644
index 00000000..80ab9ab2
--- /dev/null
+++ b/sys/pmio/tf/miopli.x
@@ -0,0 +1,102 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include <plio.h>
+include "../mio.h"
+
+# MIO_PLSEG -- Put a line segment to a masked image. A line segment is a
+# region of the data image for which the corresponding region of the mask has
+# the constant nonzero value MVAL. Line segments are returned for each line in
+# the region VS to VE, returning the number of pixels in each line segment as
+# the function value, or EOF when the region is exhausted. Once EOF is
+# reached, repeated calls will continue to return EOF until the next call to
+# MIO_SETRANGE. Repeated calls to MIO_SETRANGE may be used to access a series
+# of distinct regions in the image. If a subregion of the image is being
+# accessed with MIO_SETRANGE, the vector coordinates V returned below will
+# be relative to the defined subregion (if this is not what is desired,
+# the range should be set to the full image and a region mask used to mask
+# off the subregion to be accessed).
+
+int procedure mio_plsegi (mp, ptr, mval, v, npix)
+
+pointer mp #I MIO descriptor
+pointer ptr #O pointer to a buffer containing the data
+int mval #O mask value for the output line segment
+long v[IM_MAXDIM] #U vector coordinates of first pixel
+int npix #O number of pixels in output line segment
+
+int x1, i
+long ve[IM_MAXDIM]
+pointer pm, im, rl, rp, bp
+pointer impl2i(), impl3i(), impgsi()
+errchk impl2i, impl3i, impgsi, pm_glri
+bool pm_sectnotempty()
+int plloop()
+
+begin
+ pm = M_PM(mp)
+ rl = M_RLP(mp)
+
+ # Initialization performed for the first i/o on a new region.
+ if (M_ACTIVE(mp) == NO) {
+ call plsslv (pm, M_VS(mp,1), M_VN(mp,1), M_V(mp,1), M_VE(mp,1))
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ M_ACTIVE(mp) = YES
+ }
+
+ # Get a new mask line?
+ while (M_RLI(mp) > RLI_LEN(rl))
+ if (plloop (M_V(mp,1), M_VS(mp,1), M_VE(mp,1),
+ M_NDIM(mp)) == LOOP_DONE) {
+ return (EOF)
+ } else {
+ call amovl (M_V(mp,1), ve, M_NDIM(mp))
+ ve[1] = M_VE(mp,1)
+ if (pm_sectnotempty (pm, M_V(mp,1), ve, M_NDIM(mp))) {
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ }
+ }
+
+
+ # Get a new image line?
+ if (M_RLI(mp) == RL_FIRST) {
+ call amovl (M_V(mp,1), v, IM_MAXDIM)
+ im = M_IM(mp)
+
+ if (M_LINEIO(mp) == YES && M_NDIM(mp) == 2)
+ bp = impl2i (im, v[2])
+ else if (M_LINEIO(mp) == YES && M_NDIM(mp) == 3)
+ bp = impl3i (im, v[2], v[3])
+ else
+ bp = impgsi (im, v, ve, M_NDIM(mp))
+
+ M_LBP(mp) = bp
+ } else
+ bp = M_LBP(mp)
+
+ # Return the next line segment.
+ rp = rl + (M_RLI(mp) - 1) * RL_LENELEM
+ M_RLI(mp) = M_RLI(mp) + 1
+
+ x1 = Memi[rp+RL_XOFF]
+ npix = Memi[rp+RL_NOFF]
+ mval = Memi[rp+RL_VOFF]
+ ptr = bp + x1 - M_VS(mp,1)
+
+ if (M_REGCOORDS(mp) == NO) {
+ v[1] = x1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i)
+ } else {
+ v[1] = x1 - M_VS(mp,1) + 1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i) - M_VS(mp,i) + 1
+ }
+
+ return (npix)
+end
diff --git a/sys/pmio/tf/miopll.x b/sys/pmio/tf/miopll.x
new file mode 100644
index 00000000..c59564b4
--- /dev/null
+++ b/sys/pmio/tf/miopll.x
@@ -0,0 +1,102 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include <plio.h>
+include "../mio.h"
+
+# MIO_PLSEG -- Put a line segment to a masked image. A line segment is a
+# region of the data image for which the corresponding region of the mask has
+# the constant nonzero value MVAL. Line segments are returned for each line in
+# the region VS to VE, returning the number of pixels in each line segment as
+# the function value, or EOF when the region is exhausted. Once EOF is
+# reached, repeated calls will continue to return EOF until the next call to
+# MIO_SETRANGE. Repeated calls to MIO_SETRANGE may be used to access a series
+# of distinct regions in the image. If a subregion of the image is being
+# accessed with MIO_SETRANGE, the vector coordinates V returned below will
+# be relative to the defined subregion (if this is not what is desired,
+# the range should be set to the full image and a region mask used to mask
+# off the subregion to be accessed).
+
+int procedure mio_plsegl (mp, ptr, mval, v, npix)
+
+pointer mp #I MIO descriptor
+pointer ptr #O pointer to a buffer containing the data
+int mval #O mask value for the output line segment
+long v[IM_MAXDIM] #U vector coordinates of first pixel
+int npix #O number of pixels in output line segment
+
+int x1, i
+long ve[IM_MAXDIM]
+pointer pm, im, rl, rp, bp
+pointer impl2l(), impl3l(), impgsl()
+errchk impl2l, impl3l, impgsl, pm_glri
+bool pm_sectnotempty()
+int plloop()
+
+begin
+ pm = M_PM(mp)
+ rl = M_RLP(mp)
+
+ # Initialization performed for the first i/o on a new region.
+ if (M_ACTIVE(mp) == NO) {
+ call plsslv (pm, M_VS(mp,1), M_VN(mp,1), M_V(mp,1), M_VE(mp,1))
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ M_ACTIVE(mp) = YES
+ }
+
+ # Get a new mask line?
+ while (M_RLI(mp) > RLI_LEN(rl))
+ if (plloop (M_V(mp,1), M_VS(mp,1), M_VE(mp,1),
+ M_NDIM(mp)) == LOOP_DONE) {
+ return (EOF)
+ } else {
+ call amovl (M_V(mp,1), ve, M_NDIM(mp))
+ ve[1] = M_VE(mp,1)
+ if (pm_sectnotempty (pm, M_V(mp,1), ve, M_NDIM(mp))) {
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ }
+ }
+
+
+ # Get a new image line?
+ if (M_RLI(mp) == RL_FIRST) {
+ call amovl (M_V(mp,1), v, IM_MAXDIM)
+ im = M_IM(mp)
+
+ if (M_LINEIO(mp) == YES && M_NDIM(mp) == 2)
+ bp = impl2l (im, v[2])
+ else if (M_LINEIO(mp) == YES && M_NDIM(mp) == 3)
+ bp = impl3l (im, v[2], v[3])
+ else
+ bp = impgsl (im, v, ve, M_NDIM(mp))
+
+ M_LBP(mp) = bp
+ } else
+ bp = M_LBP(mp)
+
+ # Return the next line segment.
+ rp = rl + (M_RLI(mp) - 1) * RL_LENELEM
+ M_RLI(mp) = M_RLI(mp) + 1
+
+ x1 = Memi[rp+RL_XOFF]
+ npix = Memi[rp+RL_NOFF]
+ mval = Memi[rp+RL_VOFF]
+ ptr = bp + x1 - M_VS(mp,1)
+
+ if (M_REGCOORDS(mp) == NO) {
+ v[1] = x1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i)
+ } else {
+ v[1] = x1 - M_VS(mp,1) + 1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i) - M_VS(mp,i) + 1
+ }
+
+ return (npix)
+end
diff --git a/sys/pmio/tf/mioplr.x b/sys/pmio/tf/mioplr.x
new file mode 100644
index 00000000..05471efd
--- /dev/null
+++ b/sys/pmio/tf/mioplr.x
@@ -0,0 +1,102 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include <plio.h>
+include "../mio.h"
+
+# MIO_PLSEG -- Put a line segment to a masked image. A line segment is a
+# region of the data image for which the corresponding region of the mask has
+# the constant nonzero value MVAL. Line segments are returned for each line in
+# the region VS to VE, returning the number of pixels in each line segment as
+# the function value, or EOF when the region is exhausted. Once EOF is
+# reached, repeated calls will continue to return EOF until the next call to
+# MIO_SETRANGE. Repeated calls to MIO_SETRANGE may be used to access a series
+# of distinct regions in the image. If a subregion of the image is being
+# accessed with MIO_SETRANGE, the vector coordinates V returned below will
+# be relative to the defined subregion (if this is not what is desired,
+# the range should be set to the full image and a region mask used to mask
+# off the subregion to be accessed).
+
+int procedure mio_plsegr (mp, ptr, mval, v, npix)
+
+pointer mp #I MIO descriptor
+pointer ptr #O pointer to a buffer containing the data
+int mval #O mask value for the output line segment
+long v[IM_MAXDIM] #U vector coordinates of first pixel
+int npix #O number of pixels in output line segment
+
+int x1, i
+long ve[IM_MAXDIM]
+pointer pm, im, rl, rp, bp
+pointer impl2r(), impl3r(), impgsr()
+errchk impl2r, impl3r, impgsr, pm_glri
+bool pm_sectnotempty()
+int plloop()
+
+begin
+ pm = M_PM(mp)
+ rl = M_RLP(mp)
+
+ # Initialization performed for the first i/o on a new region.
+ if (M_ACTIVE(mp) == NO) {
+ call plsslv (pm, M_VS(mp,1), M_VN(mp,1), M_V(mp,1), M_VE(mp,1))
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ M_ACTIVE(mp) = YES
+ }
+
+ # Get a new mask line?
+ while (M_RLI(mp) > RLI_LEN(rl))
+ if (plloop (M_V(mp,1), M_VS(mp,1), M_VE(mp,1),
+ M_NDIM(mp)) == LOOP_DONE) {
+ return (EOF)
+ } else {
+ call amovl (M_V(mp,1), ve, M_NDIM(mp))
+ ve[1] = M_VE(mp,1)
+ if (pm_sectnotempty (pm, M_V(mp,1), ve, M_NDIM(mp))) {
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ }
+ }
+
+
+ # Get a new image line?
+ if (M_RLI(mp) == RL_FIRST) {
+ call amovl (M_V(mp,1), v, IM_MAXDIM)
+ im = M_IM(mp)
+
+ if (M_LINEIO(mp) == YES && M_NDIM(mp) == 2)
+ bp = impl2r (im, v[2])
+ else if (M_LINEIO(mp) == YES && M_NDIM(mp) == 3)
+ bp = impl3r (im, v[2], v[3])
+ else
+ bp = impgsr (im, v, ve, M_NDIM(mp))
+
+ M_LBP(mp) = bp
+ } else
+ bp = M_LBP(mp)
+
+ # Return the next line segment.
+ rp = rl + (M_RLI(mp) - 1) * RL_LENELEM
+ M_RLI(mp) = M_RLI(mp) + 1
+
+ x1 = Memi[rp+RL_XOFF]
+ npix = Memi[rp+RL_NOFF]
+ mval = Memi[rp+RL_VOFF]
+ ptr = bp + x1 - M_VS(mp,1)
+
+ if (M_REGCOORDS(mp) == NO) {
+ v[1] = x1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i)
+ } else {
+ v[1] = x1 - M_VS(mp,1) + 1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i) - M_VS(mp,i) + 1
+ }
+
+ return (npix)
+end
diff --git a/sys/pmio/tf/miopls.x b/sys/pmio/tf/miopls.x
new file mode 100644
index 00000000..85288e28
--- /dev/null
+++ b/sys/pmio/tf/miopls.x
@@ -0,0 +1,102 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include <plio.h>
+include "../mio.h"
+
+# MIO_PLSEG -- Put a line segment to a masked image. A line segment is a
+# region of the data image for which the corresponding region of the mask has
+# the constant nonzero value MVAL. Line segments are returned for each line in
+# the region VS to VE, returning the number of pixels in each line segment as
+# the function value, or EOF when the region is exhausted. Once EOF is
+# reached, repeated calls will continue to return EOF until the next call to
+# MIO_SETRANGE. Repeated calls to MIO_SETRANGE may be used to access a series
+# of distinct regions in the image. If a subregion of the image is being
+# accessed with MIO_SETRANGE, the vector coordinates V returned below will
+# be relative to the defined subregion (if this is not what is desired,
+# the range should be set to the full image and a region mask used to mask
+# off the subregion to be accessed).
+
+int procedure mio_plsegs (mp, ptr, mval, v, npix)
+
+pointer mp #I MIO descriptor
+pointer ptr #O pointer to a buffer containing the data
+int mval #O mask value for the output line segment
+long v[IM_MAXDIM] #U vector coordinates of first pixel
+int npix #O number of pixels in output line segment
+
+int x1, i
+long ve[IM_MAXDIM]
+pointer pm, im, rl, rp, bp
+pointer impl2s(), impl3s(), impgss()
+errchk impl2s, impl3s, impgss, pm_glri
+bool pm_sectnotempty()
+int plloop()
+
+begin
+ pm = M_PM(mp)
+ rl = M_RLP(mp)
+
+ # Initialization performed for the first i/o on a new region.
+ if (M_ACTIVE(mp) == NO) {
+ call plsslv (pm, M_VS(mp,1), M_VN(mp,1), M_V(mp,1), M_VE(mp,1))
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ M_ACTIVE(mp) = YES
+ }
+
+ # Get a new mask line?
+ while (M_RLI(mp) > RLI_LEN(rl))
+ if (plloop (M_V(mp,1), M_VS(mp,1), M_VE(mp,1),
+ M_NDIM(mp)) == LOOP_DONE) {
+ return (EOF)
+ } else {
+ call amovl (M_V(mp,1), ve, M_NDIM(mp))
+ ve[1] = M_VE(mp,1)
+ if (pm_sectnotempty (pm, M_V(mp,1), ve, M_NDIM(mp))) {
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ }
+ }
+
+
+ # Get a new image line?
+ if (M_RLI(mp) == RL_FIRST) {
+ call amovl (M_V(mp,1), v, IM_MAXDIM)
+ im = M_IM(mp)
+
+ if (M_LINEIO(mp) == YES && M_NDIM(mp) == 2)
+ bp = impl2s (im, v[2])
+ else if (M_LINEIO(mp) == YES && M_NDIM(mp) == 3)
+ bp = impl3s (im, v[2], v[3])
+ else
+ bp = impgss (im, v, ve, M_NDIM(mp))
+
+ M_LBP(mp) = bp
+ } else
+ bp = M_LBP(mp)
+
+ # Return the next line segment.
+ rp = rl + (M_RLI(mp) - 1) * RL_LENELEM
+ M_RLI(mp) = M_RLI(mp) + 1
+
+ x1 = Memi[rp+RL_XOFF]
+ npix = Memi[rp+RL_NOFF]
+ mval = Memi[rp+RL_VOFF]
+ ptr = bp + x1 - M_VS(mp,1)
+
+ if (M_REGCOORDS(mp) == NO) {
+ v[1] = x1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i)
+ } else {
+ v[1] = x1 - M_VS(mp,1) + 1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i) - M_VS(mp,i) + 1
+ }
+
+ return (npix)
+end
diff --git a/sys/pmio/tf/mioplx.x b/sys/pmio/tf/mioplx.x
new file mode 100644
index 00000000..238cb7eb
--- /dev/null
+++ b/sys/pmio/tf/mioplx.x
@@ -0,0 +1,102 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include <plio.h>
+include "../mio.h"
+
+# MIO_PLSEG -- Put a line segment to a masked image. A line segment is a
+# region of the data image for which the corresponding region of the mask has
+# the constant nonzero value MVAL. Line segments are returned for each line in
+# the region VS to VE, returning the number of pixels in each line segment as
+# the function value, or EOF when the region is exhausted. Once EOF is
+# reached, repeated calls will continue to return EOF until the next call to
+# MIO_SETRANGE. Repeated calls to MIO_SETRANGE may be used to access a series
+# of distinct regions in the image. If a subregion of the image is being
+# accessed with MIO_SETRANGE, the vector coordinates V returned below will
+# be relative to the defined subregion (if this is not what is desired,
+# the range should be set to the full image and a region mask used to mask
+# off the subregion to be accessed).
+
+int procedure mio_plsegx (mp, ptr, mval, v, npix)
+
+pointer mp #I MIO descriptor
+pointer ptr #O pointer to a buffer containing the data
+int mval #O mask value for the output line segment
+long v[IM_MAXDIM] #U vector coordinates of first pixel
+int npix #O number of pixels in output line segment
+
+int x1, i
+long ve[IM_MAXDIM]
+pointer pm, im, rl, rp, bp
+pointer impl2x(), impl3x(), impgsx()
+errchk impl2x, impl3x, impgsx, pm_glri
+bool pm_sectnotempty()
+int plloop()
+
+begin
+ pm = M_PM(mp)
+ rl = M_RLP(mp)
+
+ # Initialization performed for the first i/o on a new region.
+ if (M_ACTIVE(mp) == NO) {
+ call plsslv (pm, M_VS(mp,1), M_VN(mp,1), M_V(mp,1), M_VE(mp,1))
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ M_ACTIVE(mp) = YES
+ }
+
+ # Get a new mask line?
+ while (M_RLI(mp) > RLI_LEN(rl))
+ if (plloop (M_V(mp,1), M_VS(mp,1), M_VE(mp,1),
+ M_NDIM(mp)) == LOOP_DONE) {
+ return (EOF)
+ } else {
+ call amovl (M_V(mp,1), ve, M_NDIM(mp))
+ ve[1] = M_VE(mp,1)
+ if (pm_sectnotempty (pm, M_V(mp,1), ve, M_NDIM(mp))) {
+ call pm_glri (pm,
+ M_V(mp,1), Memi[rl], M_DEPTH(mp), M_VN(mp,1), PIX_SRC)
+ M_RLI(mp) = RL_FIRST
+ }
+ }
+
+
+ # Get a new image line?
+ if (M_RLI(mp) == RL_FIRST) {
+ call amovl (M_V(mp,1), v, IM_MAXDIM)
+ im = M_IM(mp)
+
+ if (M_LINEIO(mp) == YES && M_NDIM(mp) == 2)
+ bp = impl2x (im, v[2])
+ else if (M_LINEIO(mp) == YES && M_NDIM(mp) == 3)
+ bp = impl3x (im, v[2], v[3])
+ else
+ bp = impgsx (im, v, ve, M_NDIM(mp))
+
+ M_LBP(mp) = bp
+ } else
+ bp = M_LBP(mp)
+
+ # Return the next line segment.
+ rp = rl + (M_RLI(mp) - 1) * RL_LENELEM
+ M_RLI(mp) = M_RLI(mp) + 1
+
+ x1 = Memi[rp+RL_XOFF]
+ npix = Memi[rp+RL_NOFF]
+ mval = Memi[rp+RL_VOFF]
+ ptr = bp + x1 - M_VS(mp,1)
+
+ if (M_REGCOORDS(mp) == NO) {
+ v[1] = x1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i)
+ } else {
+ v[1] = x1 - M_VS(mp,1) + 1
+ do i = 2, M_NDIM(mp)
+ v[i] = M_V(mp,i) - M_VS(mp,i) + 1
+ }
+
+ return (npix)
+end
diff --git a/sys/pmio/tf/mkpkg b/sys/pmio/tf/mkpkg
new file mode 100644
index 00000000..2d51c91e
--- /dev/null
+++ b/sys/pmio/tf/mkpkg
@@ -0,0 +1,33 @@
+# Update the type expanded generic files in the PMIO package library.
+
+$checkout libex.a lib$
+$update libex.a
+$checkin libex.a lib$
+$exit
+
+libex.a:
+ miogld.x ../mio.h <imhdr.h> <plio.h> <pmset.h>
+ miogli.x ../mio.h <imhdr.h> <plio.h> <pmset.h>
+ miogll.x ../mio.h <imhdr.h> <plio.h> <pmset.h>
+ mioglr.x ../mio.h <imhdr.h> <plio.h> <pmset.h>
+ miogls.x ../mio.h <imhdr.h> <plio.h> <pmset.h>
+ mioglx.x ../mio.h <imhdr.h> <plio.h> <pmset.h>
+ miopld.x ../mio.h <imhdr.h> <plio.h> <pmset.h>
+ miopli.x ../mio.h <imhdr.h> <plio.h> <pmset.h>
+ miopll.x ../mio.h <imhdr.h> <plio.h> <pmset.h>
+ mioplr.x ../mio.h <imhdr.h> <plio.h> <pmset.h>
+ miopls.x ../mio.h <imhdr.h> <plio.h> <pmset.h>
+ mioplx.x ../mio.h <imhdr.h> <plio.h> <pmset.h>
+ pmglpi.x ../pmio.com <plio.h> <pmset.h>
+ pmglpl.x ../pmio.com <plio.h> <pmset.h>
+ pmglps.x ../pmio.com <plio.h> <pmset.h>
+ pmglri.x ../pmio.com <imhdr.h> <plio.h> <pmset.h>
+ pmglrl.x ../pmio.com <imhdr.h> <plio.h> <pmset.h>
+ pmglrs.x ../pmio.com <imhdr.h> <plio.h> <pmset.h>
+ pmplpi.x ../pmio.com <plio.h> <pmset.h>
+ pmplpl.x ../pmio.com <plio.h> <pmset.h>
+ pmplps.x ../pmio.com <plio.h> <pmset.h>
+ pmplri.x ../pmio.com <plio.h> <pmset.h>
+ pmplrl.x ../pmio.com <plio.h> <pmset.h>
+ pmplrs.x ../pmio.com <plio.h> <pmset.h>
+ ;
diff --git a/sys/pmio/tf/pmglpi.x b/sys/pmio/tf/pmglpi.x
new file mode 100644
index 00000000..2de53760
--- /dev/null
+++ b/sys/pmio/tf/pmglpi.x
@@ -0,0 +1,69 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <plio.h>
+
+# PM_GLP -- Get a line segment as a pixel array, applying the given ROP to
+# combine the pixels with those of the output array.
+
+procedure pm_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 temp, np, step, xstep
+pointer sp, px_src, px_out, im
+include "../pmio.com"
+
+begin
+ im = PM_REFIM(pl)
+ if (PM_MAPXY(pl) == NO) {
+ call pl_glpi (pl, v, px_dst, px_depth, npix, rop)
+ return
+ }
+
+ call smark (sp)
+
+ # Determine physical coords of line segment.
+ call amovl (v, v3, PM_MAXDIM)
+ call imaplv (im, v3, v1, PM_MAXDIM)
+ v3[1] = v3[1] + npix - 1
+ call imaplv (im, v3, v2, PM_MAXDIM)
+
+ # Get line scaling parameters.
+ if (npix <= 1)
+ xstep = 1
+ else
+ xstep = (v2[1] - v1[1]) / (npix - 1)
+ step = xstep
+ if (xstep < 0) {
+ temp = v1[1]; v1[1] = v2[1]; v2[1] = temp
+ step = -step
+ }
+
+ # Extract the pixels.
+ np = (npix - 1) * step + 1
+ call salloc (px_src, np, TY_INT)
+ call pl_glpi (pl, v1, Memi[px_src], 0, np, PIX_SRC)
+
+ # Subsample and flip if necessary.
+ if (step > 1)
+ call imsamp (Memi[px_src], Memi[px_src], npix, SZ_INT, step)
+ if (xstep < 0)
+ call imaflp (Memi[px_src], npix, SZ_INT)
+
+ if (!R_NEED_DST(rop))
+ call amovi (Memi[px_src], px_dst, npix)
+ else {
+ call salloc (px_out, npix, TY_INT)
+ call pl_pixropi (Memi[px_src], 1, PL_MAXVAL(pl), px_dst, 1,
+ MV(px_depth), npix, rop)
+ call amovi (Memi[px_out], px_dst, npix)
+ }
+
+ call sfree (sp)
+end
diff --git a/sys/pmio/tf/pmglpl.x b/sys/pmio/tf/pmglpl.x
new file mode 100644
index 00000000..24e4b6ff
--- /dev/null
+++ b/sys/pmio/tf/pmglpl.x
@@ -0,0 +1,69 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <plio.h>
+
+# PM_GLP -- Get a line segment as a pixel array, applying the given ROP to
+# combine the pixels with those of the output array.
+
+procedure pm_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 temp, np, step, xstep
+pointer sp, px_src, px_out, im
+include "../pmio.com"
+
+begin
+ im = PM_REFIM(pl)
+ if (PM_MAPXY(pl) == NO) {
+ call pl_glpl (pl, v, px_dst, px_depth, npix, rop)
+ return
+ }
+
+ call smark (sp)
+
+ # Determine physical coords of line segment.
+ call amovl (v, v3, PM_MAXDIM)
+ call imaplv (im, v3, v1, PM_MAXDIM)
+ v3[1] = v3[1] + npix - 1
+ call imaplv (im, v3, v2, PM_MAXDIM)
+
+ # Get line scaling parameters.
+ if (npix <= 1)
+ xstep = 1
+ else
+ xstep = (v2[1] - v1[1]) / (npix - 1)
+ step = xstep
+ if (xstep < 0) {
+ temp = v1[1]; v1[1] = v2[1]; v2[1] = temp
+ step = -step
+ }
+
+ # Extract the pixels.
+ np = (npix - 1) * step + 1
+ call salloc (px_src, np, TY_LONG)
+ call pl_glpl (pl, v1, Meml[px_src], 0, np, PIX_SRC)
+
+ # Subsample and flip if necessary.
+ if (step > 1)
+ call imsamp (Meml[px_src], Meml[px_src], npix, SZ_LONG, step)
+ if (xstep < 0)
+ call imaflp (Meml[px_src], npix, SZ_LONG)
+
+ if (!R_NEED_DST(rop))
+ call amovl (Meml[px_src], px_dst, npix)
+ else {
+ call salloc (px_out, npix, TY_LONG)
+ call pl_pixropl (Meml[px_src], 1, PL_MAXVAL(pl), px_dst, 1,
+ MV(px_depth), npix, rop)
+ call amovl (Meml[px_out], px_dst, npix)
+ }
+
+ call sfree (sp)
+end
diff --git a/sys/pmio/tf/pmglps.x b/sys/pmio/tf/pmglps.x
new file mode 100644
index 00000000..bcc50de4
--- /dev/null
+++ b/sys/pmio/tf/pmglps.x
@@ -0,0 +1,69 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <plio.h>
+
+# PM_GLP -- Get a line segment as a pixel array, applying the given ROP to
+# combine the pixels with those of the output array.
+
+procedure pm_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 temp, np, step, xstep
+pointer sp, px_src, px_out, im
+include "../pmio.com"
+
+begin
+ im = PM_REFIM(pl)
+ if (PM_MAPXY(pl) == NO) {
+ call pl_glps (pl, v, px_dst, px_depth, npix, rop)
+ return
+ }
+
+ call smark (sp)
+
+ # Determine physical coords of line segment.
+ call amovl (v, v3, PM_MAXDIM)
+ call imaplv (im, v3, v1, PM_MAXDIM)
+ v3[1] = v3[1] + npix - 1
+ call imaplv (im, v3, v2, PM_MAXDIM)
+
+ # Get line scaling parameters.
+ if (npix <= 1)
+ xstep = 1
+ else
+ xstep = (v2[1] - v1[1]) / (npix - 1)
+ step = xstep
+ if (xstep < 0) {
+ temp = v1[1]; v1[1] = v2[1]; v2[1] = temp
+ step = -step
+ }
+
+ # Extract the pixels.
+ np = (npix - 1) * step + 1
+ call salloc (px_src, np, TY_SHORT)
+ call pl_glps (pl, v1, Mems[px_src], 0, np, PIX_SRC)
+
+ # Subsample and flip if necessary.
+ if (step > 1)
+ call imsamp (Mems[px_src], Mems[px_src], npix, SZ_SHORT, step)
+ if (xstep < 0)
+ call imaflp (Mems[px_src], npix, SZ_SHORT)
+
+ if (!R_NEED_DST(rop))
+ call amovs (Mems[px_src], px_dst, npix)
+ else {
+ call salloc (px_out, npix, TY_SHORT)
+ call pl_pixrops (Mems[px_src], 1, PL_MAXVAL(pl), px_dst, 1,
+ MV(px_depth), npix, rop)
+ call amovs (Mems[px_out], px_dst, npix)
+ }
+
+ call sfree (sp)
+end
diff --git a/sys/pmio/tf/pmglri.x b/sys/pmio/tf/pmglri.x
new file mode 100644
index 00000000..3b3881f8
--- /dev/null
+++ b/sys/pmio/tf/pmglri.x
@@ -0,0 +1,81 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include <plio.h>
+
+# PM_GLR -- Get a line segment as a range list, applying the given ROP to
+# combine the pixels with those of the output line list. Note that this
+# operator uses IMIO if a section transformation is needed, hence if the
+# application also uses IMIO to directly access the mask image, care must
+# be taken to avoid confusion over the use of IMIO allocated pixel buffers.
+
+procedure pm_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[3,ARB] #O output line list
+int rl_depth #I line list depth, bits
+int npix #I number of pixels desired
+int rop #I rasterop
+
+int rl_len, temp, step, xstep, np
+pointer sp, px_src, rl_src, rl_out, im
+include "../pmio.com"
+int pl_p2ri()
+
+begin
+ im = PM_REFIM(pl)
+ if (PM_MAPXY(pl) == NO) {
+ call pl_glri (pl, v, rl_dst, rl_depth, npix, rop)
+ return
+ }
+
+ call smark (sp)
+ call salloc (rl_src, RL_MAXLEN(pl), TY_INT)
+
+ # Determine physical coords of line segment.
+ call amovl (v, v3, PM_MAXDIM)
+ call imaplv (im, v3, v1, PM_MAXDIM)
+ v3[1] = v3[1] + npix - 1
+ call imaplv (im, v3, v2, PM_MAXDIM)
+
+ # Get line scaling parameters.
+ if (npix <= 1)
+ xstep = 1
+ else
+ xstep = (v2[1] - v1[1]) / (npix - 1)
+ step = xstep
+ if (xstep < 0) {
+ temp = v1[1]; v1[1] = v2[1]; v2[1] = temp
+ step = -step
+ }
+
+ # Extract the pixels.
+ np = (npix - 1) * step + 1
+ call salloc (px_src, np, TY_INT)
+ call pl_glpi (pl, v1, Memi[px_src], 0, np, PIX_SRC)
+
+ # Subsample and flip if necessary.
+ if (step > 1)
+ call imsamp (Memi[px_src], Memi[px_src], npix, SZ_INT, step)
+ if (xstep < 0)
+ call imaflp (Memi[px_src], npix, SZ_INT)
+
+ # Convert to a range list.
+ rl_len = pl_p2ri (Memi[px_src], 1, Memi[rl_src], npix)
+
+ # Copy to or combine with destination.
+ if (!R_NEED_DST(rop)) {
+ rl_len = RLI_LEN(rl_src) * RL_LENELEM
+ call amovi (Memi[rl_src], rl_dst, rl_len)
+ } else {
+ call salloc (rl_out, RL_MAXLEN(pl), TY_INT)
+ call pl_rangeropi (Memi[rl_src], 1, PL_MAXVAL(pl), rl_dst, 1,
+ MV(rl_depth), Memi[rl_out], npix, rop)
+ rl_len = RLI_LEN(rl_out) * RL_LENELEM
+ call amovi (Memi[rl_out], rl_dst, rl_len)
+ }
+
+ call sfree (sp)
+end
diff --git a/sys/pmio/tf/pmglrl.x b/sys/pmio/tf/pmglrl.x
new file mode 100644
index 00000000..d78b891e
--- /dev/null
+++ b/sys/pmio/tf/pmglrl.x
@@ -0,0 +1,81 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include <plio.h>
+
+# PM_GLR -- Get a line segment as a range list, applying the given ROP to
+# combine the pixels with those of the output line list. Note that this
+# operator uses IMIO if a section transformation is needed, hence if the
+# application also uses IMIO to directly access the mask image, care must
+# be taken to avoid confusion over the use of IMIO allocated pixel buffers.
+
+procedure pm_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[3,ARB] #O output line list
+int rl_depth #I line list depth, bits
+int npix #I number of pixels desired
+int rop #I rasterop
+
+int rl_len, temp, step, xstep, np
+pointer sp, px_src, rl_src, rl_out, im
+include "../pmio.com"
+int pl_p2rl()
+
+begin
+ im = PM_REFIM(pl)
+ if (PM_MAPXY(pl) == NO) {
+ call pl_glrl (pl, v, rl_dst, rl_depth, npix, rop)
+ return
+ }
+
+ call smark (sp)
+ call salloc (rl_src, RL_MAXLEN(pl), TY_LONG)
+
+ # Determine physical coords of line segment.
+ call amovl (v, v3, PM_MAXDIM)
+ call imaplv (im, v3, v1, PM_MAXDIM)
+ v3[1] = v3[1] + npix - 1
+ call imaplv (im, v3, v2, PM_MAXDIM)
+
+ # Get line scaling parameters.
+ if (npix <= 1)
+ xstep = 1
+ else
+ xstep = (v2[1] - v1[1]) / (npix - 1)
+ step = xstep
+ if (xstep < 0) {
+ temp = v1[1]; v1[1] = v2[1]; v2[1] = temp
+ step = -step
+ }
+
+ # Extract the pixels.
+ np = (npix - 1) * step + 1
+ call salloc (px_src, np, TY_LONG)
+ call pl_glpl (pl, v1, Meml[px_src], 0, np, PIX_SRC)
+
+ # Subsample and flip if necessary.
+ if (step > 1)
+ call imsamp (Meml[px_src], Meml[px_src], npix, SZ_LONG, step)
+ if (xstep < 0)
+ call imaflp (Meml[px_src], npix, SZ_LONG)
+
+ # Convert to a range list.
+ rl_len = pl_p2rl (Meml[px_src], 1, Meml[rl_src], npix)
+
+ # Copy to or combine with destination.
+ if (!R_NEED_DST(rop)) {
+ rl_len = RLI_LEN(rl_src) * RL_LENELEM
+ call amovl (Meml[rl_src], rl_dst, rl_len)
+ } else {
+ call salloc (rl_out, RL_MAXLEN(pl), TY_LONG)
+ call pl_rangeropl (Meml[rl_src], 1, PL_MAXVAL(pl), rl_dst, 1,
+ MV(rl_depth), Meml[rl_out], npix, rop)
+ rl_len = RLI_LEN(rl_out) * RL_LENELEM
+ call amovl (Meml[rl_out], rl_dst, rl_len)
+ }
+
+ call sfree (sp)
+end
diff --git a/sys/pmio/tf/pmglrs.x b/sys/pmio/tf/pmglrs.x
new file mode 100644
index 00000000..79fea4f6
--- /dev/null
+++ b/sys/pmio/tf/pmglrs.x
@@ -0,0 +1,81 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <imhdr.h>
+include <pmset.h>
+include <plio.h>
+
+# PM_GLR -- Get a line segment as a range list, applying the given ROP to
+# combine the pixels with those of the output line list. Note that this
+# operator uses IMIO if a section transformation is needed, hence if the
+# application also uses IMIO to directly access the mask image, care must
+# be taken to avoid confusion over the use of IMIO allocated pixel buffers.
+
+procedure pm_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[3,ARB] #O output line list
+int rl_depth #I line list depth, bits
+int npix #I number of pixels desired
+int rop #I rasterop
+
+int rl_len, temp, step, xstep, np
+pointer sp, px_src, rl_src, rl_out, im
+include "../pmio.com"
+int pl_p2rs()
+
+begin
+ im = PM_REFIM(pl)
+ if (PM_MAPXY(pl) == NO) {
+ call pl_glrs (pl, v, rl_dst, rl_depth, npix, rop)
+ return
+ }
+
+ call smark (sp)
+ call salloc (rl_src, RL_MAXLEN(pl), TY_SHORT)
+
+ # Determine physical coords of line segment.
+ call amovl (v, v3, PM_MAXDIM)
+ call imaplv (im, v3, v1, PM_MAXDIM)
+ v3[1] = v3[1] + npix - 1
+ call imaplv (im, v3, v2, PM_MAXDIM)
+
+ # Get line scaling parameters.
+ if (npix <= 1)
+ xstep = 1
+ else
+ xstep = (v2[1] - v1[1]) / (npix - 1)
+ step = xstep
+ if (xstep < 0) {
+ temp = v1[1]; v1[1] = v2[1]; v2[1] = temp
+ step = -step
+ }
+
+ # Extract the pixels.
+ np = (npix - 1) * step + 1
+ call salloc (px_src, np, TY_SHORT)
+ call pl_glps (pl, v1, Mems[px_src], 0, np, PIX_SRC)
+
+ # Subsample and flip if necessary.
+ if (step > 1)
+ call imsamp (Mems[px_src], Mems[px_src], npix, SZ_SHORT, step)
+ if (xstep < 0)
+ call imaflp (Mems[px_src], npix, SZ_SHORT)
+
+ # Convert to a range list.
+ rl_len = pl_p2rs (Mems[px_src], 1, Mems[rl_src], npix)
+
+ # Copy to or combine with destination.
+ if (!R_NEED_DST(rop)) {
+ rl_len = RLI_LEN(rl_src) * RL_LENELEM
+ call amovs (Mems[rl_src], rl_dst, rl_len)
+ } else {
+ call salloc (rl_out, RL_MAXLEN(pl), TY_SHORT)
+ call pl_rangerops (Mems[rl_src], 1, PL_MAXVAL(pl), rl_dst, 1,
+ MV(rl_depth), Mems[rl_out], npix, rop)
+ rl_len = RLS_LEN(rl_out) * RL_LENELEM
+ call amovs (Mems[rl_out], rl_dst, rl_len)
+ }
+
+ call sfree (sp)
+end
diff --git a/sys/pmio/tf/pmplpi.x b/sys/pmio/tf/pmplpi.x
new file mode 100644
index 00000000..b62b333a
--- /dev/null
+++ b/sys/pmio/tf/pmplpi.x
@@ -0,0 +1,34 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <plio.h>
+
+# PM_PLP -- Put a line segment input as a pixel array a mask, applying the
+# given ROP to combine the pixels with those of the mask.
+
+procedure pm_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 affected
+int rop #I rasterop
+
+pointer sp, ll_src
+int ll_len, pl_p2li()
+include "../pmio.com"
+
+begin
+ if (PM_MAPXY(pl) == NO)
+ call pl_plpi (pl, v, px_src, px_depth, npix, rop)
+ else {
+ call smark (sp)
+ call salloc (ll_src, LL_MAXLEN(pl), TY_SHORT)
+
+ ll_len = pl_p2li (px_src, 1, Mems[ll_src], npix)
+ call pm_plls (pl, v, Mems[ll_src], px_depth, npix, rop)
+
+ call sfree (sp)
+ }
+end
diff --git a/sys/pmio/tf/pmplpl.x b/sys/pmio/tf/pmplpl.x
new file mode 100644
index 00000000..2194d9f9
--- /dev/null
+++ b/sys/pmio/tf/pmplpl.x
@@ -0,0 +1,34 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <plio.h>
+
+# PM_PLP -- Put a line segment input as a pixel array a mask, applying the
+# given ROP to combine the pixels with those of the mask.
+
+procedure pm_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 affected
+int rop #I rasterop
+
+pointer sp, ll_src
+int ll_len, pl_p2ll()
+include "../pmio.com"
+
+begin
+ if (PM_MAPXY(pl) == NO)
+ call pl_plpl (pl, v, px_src, px_depth, npix, rop)
+ else {
+ call smark (sp)
+ call salloc (ll_src, LL_MAXLEN(pl), TY_SHORT)
+
+ ll_len = pl_p2ll (px_src, 1, Mems[ll_src], npix)
+ call pm_plls (pl, v, Mems[ll_src], px_depth, npix, rop)
+
+ call sfree (sp)
+ }
+end
diff --git a/sys/pmio/tf/pmplps.x b/sys/pmio/tf/pmplps.x
new file mode 100644
index 00000000..68e26f7d
--- /dev/null
+++ b/sys/pmio/tf/pmplps.x
@@ -0,0 +1,34 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <plio.h>
+
+# PM_PLP -- Put a line segment input as a pixel array a mask, applying the
+# given ROP to combine the pixels with those of the mask.
+
+procedure pm_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 affected
+int rop #I rasterop
+
+pointer sp, ll_src
+int ll_len, pl_p2ls()
+include "../pmio.com"
+
+begin
+ if (PM_MAPXY(pl) == NO)
+ call pl_plps (pl, v, px_src, px_depth, npix, rop)
+ else {
+ call smark (sp)
+ call salloc (ll_src, LL_MAXLEN(pl), TY_SHORT)
+
+ ll_len = pl_p2ls (px_src, 1, Mems[ll_src], npix)
+ call pm_plls (pl, v, Mems[ll_src], px_depth, npix, rop)
+
+ call sfree (sp)
+ }
+end
diff --git a/sys/pmio/tf/pmplri.x b/sys/pmio/tf/pmplri.x
new file mode 100644
index 00000000..4a2f1435
--- /dev/null
+++ b/sys/pmio/tf/pmplri.x
@@ -0,0 +1,34 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <plio.h>
+
+# PM_PLR -- Put a line segment input as a range list to a mask, applying the
+# given ROP to combine the pixels with those of the output mask.
+
+procedure pm_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[3,ARB] #I input range list
+int rl_depth #I range list pixel depth, bits
+int npix #I number of pixels affected
+int rop #I rasterop
+
+pointer sp, ll_src
+int ll_len, pl_r2li()
+include "../pmio.com"
+
+begin
+ if (PM_MAPXY(pl) == NO)
+ call pl_plri (pl, v, rl_src, rl_depth, npix, rop)
+ else {
+ call smark (sp)
+ call salloc (ll_src, LL_MAXLEN(pl), TY_SHORT)
+
+ ll_len = pl_r2li (rl_src, 1, Mems[ll_src], npix)
+ call pm_plls (pl, v, Mems[ll_src], rl_depth, npix, rop)
+
+ call sfree (sp)
+ }
+end
diff --git a/sys/pmio/tf/pmplrl.x b/sys/pmio/tf/pmplrl.x
new file mode 100644
index 00000000..260daa21
--- /dev/null
+++ b/sys/pmio/tf/pmplrl.x
@@ -0,0 +1,34 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <plio.h>
+
+# PM_PLR -- Put a line segment input as a range list to a mask, applying the
+# given ROP to combine the pixels with those of the output mask.
+
+procedure pm_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[3,ARB] #I input range list
+int rl_depth #I range list pixel depth, bits
+int npix #I number of pixels affected
+int rop #I rasterop
+
+pointer sp, ll_src
+int ll_len, pl_r2ll()
+include "../pmio.com"
+
+begin
+ if (PM_MAPXY(pl) == NO)
+ call pl_plrl (pl, v, rl_src, rl_depth, npix, rop)
+ else {
+ call smark (sp)
+ call salloc (ll_src, LL_MAXLEN(pl), TY_SHORT)
+
+ ll_len = pl_r2ll (rl_src, 1, Mems[ll_src], npix)
+ call pm_plls (pl, v, Mems[ll_src], rl_depth, npix, rop)
+
+ call sfree (sp)
+ }
+end
diff --git a/sys/pmio/tf/pmplrs.x b/sys/pmio/tf/pmplrs.x
new file mode 100644
index 00000000..43b99b98
--- /dev/null
+++ b/sys/pmio/tf/pmplrs.x
@@ -0,0 +1,34 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pmset.h>
+include <plio.h>
+
+# PM_PLR -- Put a line segment input as a range list to a mask, applying the
+# given ROP to combine the pixels with those of the output mask.
+
+procedure pm_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[3,ARB] #I input range list
+int rl_depth #I range list pixel depth, bits
+int npix #I number of pixels affected
+int rop #I rasterop
+
+pointer sp, ll_src
+int ll_len, pl_r2ls()
+include "../pmio.com"
+
+begin
+ if (PM_MAPXY(pl) == NO)
+ call pl_plrs (pl, v, rl_src, rl_depth, npix, rop)
+ else {
+ call smark (sp)
+ call salloc (ll_src, LL_MAXLEN(pl), TY_SHORT)
+
+ ll_len = pl_r2ls (rl_src, 1, Mems[ll_src], npix)
+ call pm_plls (pl, v, Mems[ll_src], rl_depth, npix, rop)
+
+ call sfree (sp)
+ }
+end
diff --git a/sys/pmio/zzdebug.x b/sys/pmio/zzdebug.x
new file mode 100644
index 00000000..e21e500d
--- /dev/null
+++ b/sys/pmio/zzdebug.x
@@ -0,0 +1,217 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <error.h>
+include <imhdr.h>
+include <ctype.h>
+include <fset.h>
+include <pmset.h>
+include <plio.h>
+
+task pmtest = t_pmtest,
+ mkmask = t_mkmask,
+ pmcopy = t_pmcopy,
+ mio = t_mio
+
+
+# MKMASK -- Make a mask for the given image.
+
+procedure t_mkmask()
+
+char image[SZ_FNAME]
+char mask[SZ_FNAME]
+char cmdfile[SZ_FNAME]
+char cmd[SZ_FNAME]
+
+pointer im, pm
+int x, y, r, x1, y1, x2, y2, fd
+pointer immap(), pm_newmask()
+int open(), nscan(), fscan()
+bool streq()
+
+begin
+ call clgstr ("image", image, SZ_FNAME)
+ call clgstr ("mask", mask, SZ_FNAME)
+
+ # Open the image and an empty mask.
+ im = immap (image, READ_ONLY, 0)
+ pm = pm_newmask (im, 1)
+
+ # Get the list of commands to be processed.
+ call clgstr ("cmdfile", cmdfile, SZ_FNAME)
+ fd = open (cmdfile, READ_ONLY, TEXT_FILE)
+
+ # Process the commands and draw the mask.
+ while (fscan (fd) != EOF) {
+ call gargwrd (cmd, SZ_FNAME)
+ if (nscan() < 1)
+ break
+
+ if (streq (cmd, "point")) {
+ # Command: point x y
+ call gargi (x)
+ call gargi (y)
+ if (nscan() < 3) {
+ call eprintf ("point: bad arg list\n")
+ next
+ }
+
+ call eprintf ("point %d %d\n")
+ call pargi (x); call pargi (y)
+ call pm_point (pm, x, y, PIX_SET + PIX_VALUE(1))
+
+ } else if (streq (cmd, "circle")) {
+ # Command: circle x y r
+ call gargi (x)
+ call gargi (y)
+ call gargi (r)
+ if (nscan() < 4) {
+ call eprintf ("circle: bad arg list\n")
+ next
+ }
+
+ call eprintf ("circle %d %d %d\n")
+ call pargi (x); call pargi (y); call pargi (r)
+ call pm_circle (pm, x, y, r, PIX_SET + PIX_VALUE(1))
+
+ } else if (streq (cmd, "box")) {
+ # Command: box x1 y1 x2 y2
+ call gargi (x1); call gargi (y1)
+ call gargi (x2); call gargi (y2)
+ if (nscan() < 5) {
+ call eprintf ("box: bad arg list\n")
+ next
+ }
+
+ call eprintf ("box %d %d %d %d\n")
+ call pargi (x1); call pargi (y1)
+ call pargi (x2); call pargi (y2)
+ call pm_box (pm, x1,y1, x2,y2, PIX_SET + PIX_VALUE(1))
+
+ } else {
+ call eprintf ("bad command %s\n")
+ call pargstr (cmd)
+ }
+
+ # call pm_debug (pm, STDERR, 80, PD_INDEX)
+ }
+
+ # Save the mask in a file.
+ call pm_savef (pm, mask, "mkmask", 0)
+
+ call pm_close (pm)
+ call imunmap (im)
+end
+
+
+# PMCOPY -- Copy an image mask.
+
+procedure t_pmcopy
+
+char refim[SZ_FNAME]
+char mask[SZ_FNAME], newmask[SZ_FNAME], title[SZ_LINE]
+
+pointer im, old_pm, new_pm
+long vs[PM_MAXDIM], vn[PM_MAXDIM]
+pointer immap(), pm_open(), pm_newmask()
+int pm_stati()
+
+begin
+ call clgstr ("mask", mask, SZ_FNAME)
+ call clgstr ("refim", refim, SZ_FNAME)
+ call clgstr ("newmask", newmask, SZ_FNAME)
+
+ # Open reference image.
+ im = immap (refim, READ_ONLY, 0)
+
+ # Open old mask.
+ old_pm = pm_open (NULL)
+ call pm_loadf (old_pm, mask, title, SZ_LINE)
+ call pm_seti (old_pm, P_REFIM, im)
+
+ # Create a new mask.
+ new_pm = pm_newmask (im, pm_stati(old_pm,P_DEPTH))
+
+ # Copy the mask.
+ call amovkl (1, vs, PM_MAXDIM)
+ call amovkl (IM_LEN(im,1), vn, PM_MAXDIM)
+ call pm_rop (old_pm, vs, new_pm, vs, vn, PIX_SRC)
+
+ # Save in a file.
+ call pm_savef (new_pm, newmask, title, 0)
+
+ call pm_close (new_pm)
+ call pm_close (old_pm)
+ call imunmap (im)
+end
+
+
+# MIO -- Test MIO.
+
+procedure t_mio()
+
+char image[SZ_FNAME]
+char mask[SZ_FNAME]
+
+real rsum
+pointer im, mp, pm, bp
+bool debug, usefullimage
+long v[IM_MAXDIM], vs[2], ve[2]
+int mval, npix, totpix
+
+real asums()
+bool clgetb()
+pointer immap(), mio_open()
+int clgeti(), mio_glsegs(), mio_stati(), clscan(), nscan()
+
+begin
+ call clgstr ("image", image, SZ_FNAME)
+ call clgstr ("mask", mask, SZ_FNAME)
+ debug = clgetb ("debug")
+
+ im = immap (image, READ_ONLY, 0)
+ mp = mio_open (mask, clgeti("flags"), im)
+
+ # The following assumes a 2D image.
+ usefullimage = true
+ if (clscan ("region") != EOF) {
+ call gargi(vs[1]); call gargi (vs[2])
+ call gargi(ve[1]); call gargi (ve[2])
+ usefullimage = (nscan() != 4)
+ }
+ if (usefullimage) {
+ call amovkl (1, vs, 2)
+ call amovl (IM_LEN(im,1), ve, 2)
+ }
+ call mio_setrange (mp, vs, ve, 2)
+
+ if (debug) {
+ pm = mio_stati (mp, P_PMDES)
+ call pm_debug (pm, STDERR, 80, PD_LLOUT)
+ }
+
+ totpix = 0
+ rsum = 0.0
+
+ while (mio_glsegs (mp, bp, mval, v, npix) != EOF) {
+ if (debug) {
+ call eprintf ("x=%3d, y=%3d, n=%3d, mval=%o\n")
+ call pargl (v[1])
+ call pargl (v[2])
+ call pargi (npix)
+ call pargi (mval)
+ }
+ totpix = totpix + npix
+ rsum = rsum + asums (Mems[bp], npix)
+ }
+
+ call eprintf ("totpix=%d, sum=%g, mean=%g\n")
+ call pargi (totpix)
+ call pargr (rsum)
+ if (totpix == 0)
+ call pargr (INDEFR)
+ else
+ call pargr (rsum / totpix)
+
+ call mio_close (mp)
+ call imunmap (im)
+end
diff --git a/sys/pmio/zzinterp.x b/sys/pmio/zzinterp.x
new file mode 100644
index 00000000..cd23aaf2
--- /dev/null
+++ b/sys/pmio/zzinterp.x
@@ -0,0 +1,1142 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <error.h>
+include <ctype.h>
+include <fset.h>
+include <pmset.h>
+include <plio.h>
+
+.help pmtest
+.nf -------------------------------------------------------------------------
+PMTEST -- PMIO package debug and test facility.
+
+ Due to the complexity of the PMIO package, testing is performed using an
+interactive interpreter which reads commands from the standard input.
+All commands operate internally upon a set of four mask registers A-D,
+and a set of ten vector registers V[0-9].
+
+ a,b,c,d - mask registers
+ v0,...,v9 - vector registers
+
+The following commands are defined:
+
+ help # print command summary
+ timer # toggle timing of commands
+ run fname # read commands from a file
+ clear # clear the screen
+ bye # all done (also EOF)
+
+ create [mask] naxes axlen depth # create a new mask
+ load [mask] fname # load mask from file
+ save [mask] fname [title] # save mask in file
+ loadim [mask] image # load mask from image
+ saveim [mask] image [title] # save mask in image
+ erase [mask] [vs ve] # erase a mask or region
+ draw [mask] [vs ve] [>ofile] # draw mask or region of mask
+
+ set [mask] # set reference mask
+ set [vector] i j k... # load vector register
+ show [vector] # print vector register
+ show [mask] [index] [ll] [rl] [>ofile] # print debug info for a mask
+
+ box [mask] P1 P2 rop # draw a box
+ circle [mask] P1 r rop # draw a circle
+ line [mask] P1 P2 width rop # draw a line segment
+ point [mask] P1 rop # draw a point
+ polygon [mask] P1 ... PN rop # draw a polygon
+
+ rop src [vs] dst [vs] [vn] rop # rasterop
+ stencil src [vs] dst [vs] stn [vs] [vn] rop # stencil
+
+ compare mask1 mask2 # compare two masks
+ rtest mask1 mask2 # range list conversion test
+ ptest mask1 mask2 # pixel array conversion test
+
+Rasterops may be specified either as integer constants (any radix) or via
+a simple symbolic notation, e.g.: "opcode+[value]".
+
+A mask may be examined in detail with SHOW, which calls pm_debug to decode
+the contents of a mask. A graphic image of a mask may be drawn with DRAW,
+which renders each pixel in the mask as a printable character.
+.endhelp --------------------------------------------------------------------
+
+define SZ_SBUF 512 # size limiting parameters
+define DEF_MASKSIZE_X 75
+define DEF_MASKSIZE_Y 40
+define MAXKWLEN 20
+define MAXARGS 50
+define MAXMREG 4
+define MAXVREG 10
+define MAXINCL 10
+define WIDTH 80
+
+define INT_ARG 1 # argument types
+define STRING_ARG 2
+define VECTOR_ARG 3
+define MASK_ARG 4
+
+define v_i argval[$1] # integer argument
+define v_s sbuf[argval[$1]] # string argument
+define v_si sbuf[argval[$1]+$2-1] # indexed string argument
+define v_v v_reg[1,argval[$1]+1] # vector argument
+define v_vi v_reg[$2,argval[$1]+1] # indexed vector argument
+define v_m v_mask[argval[$1]] # mask argument
+
+define KW_BOX 1 # interpreter commands
+define KW_BYE 2
+define KW_CIRCLE 3
+define KW_CLEAR 4
+define KW_COMPARE 5
+define KW_CREATE 6
+define KW_DRAW 7
+define KW_ERASE 8
+define KW_HELP 9
+# eol 10
+define KW_LINE 11
+define KW_POINT 12
+define KW_POLYGON 13
+define KW_LOAD 14
+define KW_LOADIM 15
+define KW_PTEST 16
+define KW_ROP 17
+define KW_RTEST 18
+define KW_RUN 19
+define KW_SAVE 20
+define KW_SAVEIM 21
+# eol 22
+define KW_SET 23
+define KW_SHOW 24
+define KW_STENCIL 25
+define KW_TIMER 26
+
+
+# PMTEST -- Test the PMIO package. Read and execute commands from the standard
+# input until EOF or BYE is seen.
+
+procedure t_pmtest()
+
+bool timer
+long time[2]
+int x, y, r
+int px[MAXARGS], py[MAXARGS]
+int what, rop, v_arg, x1, x2, y1, y2, ip, op, ch, i, j
+pointer pm, pm_1, pm_2, def_pm, pm_src, pm_dst, pm_stn, tty
+char cmd[SZ_LINE], kwname[SZ_FNAME], fname[SZ_FNAME], title[SZ_LINE]
+int opcode, save_fd[MAXINCL], in, fd, o_fd, maskno, depth, naxes, npts
+int v1[PL_MAXDIM], v2[PL_MAXDIM], v3[PL_MAXDIM], v4[PL_MAXDIM], v[PL_MAXDIM]
+int fstati(), strdic(), open(), getline(), strncmp()
+pointer pm_create(), ttyodes()
+
+char sbuf[SZ_SBUF]
+int v_mask[MAXMREG], v_reg[PL_MAXDIM,MAXVREG]
+int nargs, argno, argtype[MAXARGS], argval[MAXARGS], s_op, width
+common /pmzcom/ v_mask, v_reg, nargs, argno, argtype, argval, s_op, sbuf
+define argerr_ 91
+define eof_ 92
+
+string keywords "|box|bye|circle|clear|compare|create|draw|erase|help|\
+ |line|point|polygon|load|loadim|ptest|rop|rtest|run|save|saveim|\
+ |set|show|stencil|timer|"
+
+begin
+ in = 0
+ ip = 1
+ fd = STDIN
+ cmd[ip] = EOS
+ timer = false
+
+ # Initialize the mask registers.
+ v[1] = DEF_MASKSIZE_X
+ v[2] = DEF_MASKSIZE_Y
+ do i = 1, MAXMREG
+ v_mask[i] = pm_create (2, v, 7)
+ def_pm = v_mask[1]
+
+ # Initialize the vector registers.
+ do i = 1, MAXVREG
+ call amovki (1, v_reg[1,i], PL_MAXDIM)
+
+ # Main interpreter loop.
+ # ---------------------------
+
+ repeat {
+ # Get next command.
+ if (cmd[ip] == '\n' || cmd[ip] == '#' || cmd[ip] == EOS) {
+ # Prompt if reading from the standard input.
+ if (in == 0 && fstati (STDIN, F_REDIR) == NO) {
+ call putline (STDOUT, "* ")
+ call flush (STDOUT)
+ }
+
+ # Handle EOF on the current command stream.
+ if (getline (fd, cmd) == EOF) {
+eof_ if (in > 0) {
+ call close (fd)
+ fd = save_fd[in]
+ in = in - 1
+ } else
+ break
+ }
+
+ ip = 1
+ }
+
+ # Skip blank lines and comment lines.
+ for (ip=1; IS_WHITE(cmd[ip]) || cmd[ip] == ';'; ip=ip+1)
+ ;
+ if (cmd[ip] == '\n' || cmd[ip] == '#' || cmd[ip] == EOS)
+ next
+
+ # Extract the keyword into the KWNAME buffer. Leave the input
+ # pointer positioned to the first char following the keyword.
+
+ for (op=1; cmd[ip] != EOS && cmd[ip] != '\n'; ip=ip+1) {
+ ch = cmd[ip]
+ if (IS_ALNUM(ch)) {
+ kwname[op] = ch
+ op = op + 1
+ } else
+ break
+ }
+ kwname[op] = EOS
+
+ # Look up the keyword in the dictionary. If not found ring the
+ # bell, but do not quit.
+
+ opcode = strdic (kwname, kwname, MAXKWLEN, keywords)
+ if (opcode <= 0) {
+ call eprintf ("unknown command\007\n")
+ call flush (STDERR)
+ ip=1; cmd[ip] = EOS
+ next
+ }
+
+ # Parse the argument list.
+ call parse_args (cmd, ip)
+
+ # Process the command.
+ # -------------------------
+
+ switch (opcode) {
+ case KW_BYE:
+ goto eof_
+
+ case KW_POINT:
+ # Draw a point.
+
+ # Get mask.
+ pm = def_pm
+ if (argtype[argno] == MASK_ARG) {
+ pm = v_m(argno)
+ argno = argno + 1
+ }
+
+ # Get coords of point.
+ if (argtype[argno] == VECTOR_ARG) {
+ # Coords given as vectors.
+ x1 = v_vi(argno,1)
+ y1 = v_vi(argno,2)
+ argno = argno + 1
+ } else {
+ # Coords given explicitly.
+ do i = 1, 2
+ if (argtype[argno+i-1] != INT_ARG)
+ goto argerr_
+
+ x1 = v_i(argno); argno = argno + 1
+ y1 = v_i(argno); argno = argno + 1
+ }
+
+ # Get rop.
+ if (argno <= nargs) {
+ if (argtype[argno] != INT_ARG)
+ goto argerr_
+ rop = v_i(argno); argno = argno + 1
+ } else
+ rop = or (PIX_SRC, PIX_DST) + PIX_VALUE('1')
+
+ # Perform the operation.
+ if (timer)
+ call sys_mtime (time)
+ call pm_point (pm, x1, y1, rop)
+ if (timer)
+ call sys_ptime (STDOUT, "", time)
+
+ case KW_BOX:
+ # Draw a box.
+
+ # Get mask.
+ pm = def_pm
+ if (argtype[argno] == MASK_ARG) {
+ pm = v_m(argno)
+ argno = argno + 1
+ }
+
+ # Get corner coords of box.
+ if (argtype[argno] == VECTOR_ARG) {
+ # Coords given as vectors.
+ x1 = v_vi(argno,1)
+ y1 = v_vi(argno,2)
+ argno = argno + 1
+ if (argtype[argno] != VECTOR_ARG)
+ goto argerr_
+ x2 = v_vi(argno,1)
+ y2 = v_vi(argno,2)
+ argno = argno + 1
+
+ } else {
+ # Coords given explicitly.
+ do i = 1, 4
+ if (argtype[argno+i-1] != INT_ARG)
+ goto argerr_
+
+ x1 = v_i(argno); argno = argno + 1
+ y1 = v_i(argno); argno = argno + 1
+ x2 = v_i(argno); argno = argno + 1
+ y2 = v_i(argno); argno = argno + 1
+ }
+
+ # Get rop.
+ if (argno <= nargs) {
+ if (argtype[argno] != INT_ARG)
+ goto argerr_
+ rop = v_i(argno); argno = argno + 1
+ } else
+ rop = or (PIX_SRC, PIX_DST) + PIX_VALUE('2')
+
+ # Perform the operation.
+ if (timer)
+ call sys_mtime (time)
+ call pm_box (pm, x1, y1, x2, y2, rop)
+ if (timer)
+ call sys_ptime (STDOUT, "", time)
+
+ case KW_LINE:
+ # Draw a line of arbitrary orientation and width.
+
+ # Get mask.
+ pm = def_pm
+ if (argtype[argno] == MASK_ARG) {
+ pm = v_m(argno)
+ argno = argno + 1
+ }
+
+ # Get endpoints of line.
+ if (argtype[argno] == VECTOR_ARG) {
+ # Coords given as vectors.
+ x1 = v_vi(argno,1)
+ y1 = v_vi(argno,2)
+ argno = argno + 1
+ if (argtype[argno] != VECTOR_ARG)
+ goto argerr_
+ x2 = v_vi(argno,1)
+ y2 = v_vi(argno,2)
+ argno = argno + 1
+
+ } else {
+ # Coords given explicitly.
+ do i = 1, 4
+ if (argtype[argno+i-1] != INT_ARG)
+ goto argerr_
+
+ x1 = v_i(argno); argno = argno + 1
+ y1 = v_i(argno); argno = argno + 1
+ x2 = v_i(argno); argno = argno + 1
+ y2 = v_i(argno); argno = argno + 1
+ }
+
+ # Get line width.
+ if (argno <= nargs) {
+ if (argtype[argno] != INT_ARG)
+ goto argerr_
+ width = v_i(argno); argno = argno + 1
+ } else
+ width = 1
+
+ # Get rop.
+ if (argno <= nargs) {
+ if (argtype[argno] != INT_ARG)
+ goto argerr_
+ rop = v_i(argno); argno = argno + 1
+ } else
+ rop = or (PIX_SRC, PIX_DST) + PIX_VALUE('4')
+
+ # Perform the operation.
+ if (timer)
+ call sys_mtime (time)
+ call pm_line (pm, x1, y1, x2, y2, width, rop)
+ if (timer)
+ call sys_ptime (STDOUT, "", time)
+
+ case KW_CIRCLE:
+ # Draw a circle.
+
+ # Get mask.
+ pm = def_pm
+ if (argtype[argno] == MASK_ARG) {
+ pm = v_m(argno)
+ argno = argno + 1
+ }
+
+ # Get center coords and radius of circle.
+ if (argtype[argno] == VECTOR_ARG) {
+ # Center coords given as a vector.
+ x = v_vi(argno,1)
+ y = v_vi(argno,2)
+ argno = argno + 1
+
+ } else {
+ # Center coords given explicitly.
+ do i = 1, 2
+ if (argtype[argno+i-1] != INT_ARG)
+ goto argerr_
+
+ x = v_i(argno); argno = argno + 1
+ y = v_i(argno); argno = argno + 1
+ }
+
+ if (argtype[argno] != INT_ARG)
+ goto argerr_
+ r = v_i(argno); argno = argno + 1
+
+ # Get rop.
+ if (argno <= nargs) {
+ if (argtype[argno] != INT_ARG)
+ goto argerr_
+ rop = v_i(argno); argno = argno + 1
+ } else
+ rop = or (PIX_SRC, PIX_DST) + PIX_VALUE('Q')
+
+ # Perform the operation.
+ if (timer)
+ call sys_mtime (time)
+ call pm_circle (pm, x, y, r, rop)
+ if (timer)
+ call sys_ptime (STDOUT, "", time)
+
+ case KW_POLYGON:
+ # Draw a polygon.
+
+ # Get mask.
+ pm = def_pm
+ if (argtype[argno] == MASK_ARG) {
+ pm = v_m(argno)
+ argno = argno + 1
+ }
+
+ # Get the coordinates of the polygon.
+ for (npts=0; argno <= nargs; ) {
+ npts = npts + 1
+
+ if (argtype[argno] == VECTOR_ARG) {
+ # Coords of point given as a vector.
+ px[npts] = v_vi(argno,1)
+ py[npts] = v_vi(argno,2)
+ argno = argno + 1
+
+ } else if (argtype[argno] == INT_ARG &&
+ argtype[argno+1] == INT_ARG) {
+
+ # Center coords given explicitly.
+ px[npts] = v_i(argno); argno = argno + 1
+ py[npts] = v_i(argno); argno = argno + 1
+ }
+ }
+
+ # Get rop.
+ if (argno <= nargs) {
+ if (argtype[argno] != INT_ARG)
+ goto argerr_
+ rop = v_i(argno); argno = argno + 1
+ } else
+ rop = or (PIX_SRC, PIX_DST) + PIX_VALUE('R')
+
+ # Perform the operation.
+ if (timer)
+ call sys_mtime (time)
+ call pm_polygon (pm, px, py, npts, rop)
+ if (timer)
+ call sys_ptime (STDOUT, "", time)
+
+ case KW_CLEAR:
+ # Clear the screen.
+ tty = ttyodes ("terminal")
+ call ttyclear (STDOUT, tty)
+ call ttycdes (tty)
+
+ case KW_COMPARE:
+ # Compare two masks.
+ if (nargs < 2)
+ goto argerr_
+
+ # Get mask 1.
+ if (argtype[argno] == MASK_ARG) {
+ pm_1 = v_m(argno)
+ argno = argno + 1
+ } else
+ goto argerr_
+
+ # Get mask 2.
+ if (argtype[argno] == MASK_ARG) {
+ pm_2 = v_m(argno)
+ argno = argno + 1
+ } else
+ goto argerr_
+
+ # Perform the operation.
+ if (timer)
+ call sys_mtime (time)
+ call pm_compare (pm_1, pm_2, STDOUT)
+ if (timer)
+ call sys_ptime (STDOUT, "", time)
+
+ case KW_CREATE:
+ # Create a new, emtpy mask of the given size and depth.
+
+ # Get mask.
+ if (argtype[argno] == MASK_ARG) {
+ maskno = v_i(argno)
+ argno = argno + 1
+ }
+
+ # Get naxes.
+ if (argtype[argno] != INT_ARG)
+ goto argerr_
+ naxes = v_i(argno); argno = argno + 1
+
+ # Get mask size.
+ if (argtype[argno] == VECTOR_ARG) {
+ # Mask size given as vector.
+ call amovi (v_v(argno), v1, PL_MAXDIM)
+ argno = argno + 1
+ } else {
+ # Mask size given explicitly.
+ do i = 1, naxes {
+ if (argtype[argno+i-1] != INT_ARG)
+ goto argerr_
+ v1[i] = v_i(argno)
+ argno = argno + 1
+ }
+ }
+
+ # Get mask depth.
+ if (argtype[argno] != INT_ARG)
+ depth = 1
+ else {
+ depth = v_i(argno)
+ argno = argno + 1
+ }
+
+ # Perform the operation.
+ if (timer)
+ call sys_mtime (time)
+ v_mask[maskno] = pm_create (naxes, v1, depth)
+ def_pm = v_mask[maskno]
+ if (timer)
+ call sys_ptime (STDOUT, "", time)
+
+ case KW_DRAW:
+ # Draw a mask or region of a mask on the screen.
+
+ # Get mask.
+ pm = def_pm
+ if (nargs >= 1 && argtype[argno] == MASK_ARG) {
+ pm = v_m(argno)
+ argno = argno + 1
+ }
+
+ # Get vector coords of region to be drawn.
+ if (argtype[argno] == VECTOR_ARG) {
+ call amovi (v_v(argno), v1, PL_MAXDIM)
+ argno = argno + 1
+ } else
+ call amovki (1, v1, PL_MAXDIM)
+
+ if (argtype[argno] == VECTOR_ARG) {
+ call amovi (v_v(argno), v2, PL_MAXDIM)
+ argno = argno + 1
+ } else
+ call amovi (PL_AXLEN(pm,1), v2, PL_MAXDIM)
+
+ # Perform the operation.
+ call pm_asciidump (pm, v1, v2, STDOUT)
+
+ case KW_ERASE:
+ # Erase a mask, or a region of a mask.
+
+ # Get mask.
+ pm = def_pm
+ if (nargs >= 1 && argtype[argno] == MASK_ARG) {
+ pm = v_m(argno)
+ argno = argno + 1
+ }
+
+ # Get vector coords of region to be erased.
+ if (argtype[argno] == VECTOR_ARG) {
+ call amovi (v_v(argno), v1, PL_MAXDIM)
+ argno = argno + 1
+ } else
+ call amovki (1, v1, PL_MAXDIM)
+
+ if (argtype[argno] == VECTOR_ARG) {
+ call amovi (v_v(argno), v2, PL_MAXDIM)
+ argno = argno + 1
+ } else
+ call amovi (PL_AXLEN(pm,1), v2, PL_MAXDIM)
+
+ # Perform the operation.
+ if (timer)
+ call sys_mtime (time)
+ if (nargs <= 1)
+ call pm_clear (pm)
+ else
+ call pm_rop (NULL, 0, pm, v1, v2, PIX_CLR)
+ if (timer)
+ call sys_ptime (STDOUT, "", time)
+
+ case KW_HELP:
+ # Print a command summary.
+ call print_help (STDOUT)
+
+ case KW_RUN:
+ # Read commands from a file.
+ if (nargs < 1 || argtype[argno] != STRING_ARG)
+ goto argerr_
+
+ in = in + 1
+ if (in > MAXINCL)
+ call error (1, "too many nested run files\n")
+ save_fd[in] = fd
+ iferr (fd = open (v_s(argno), READ_ONLY, TEXT_FILE)) {
+ call erract (EA_WARN)
+ fd = save_fd[in]
+ in = in - 1
+ }
+
+ case KW_SET:
+ # Set the value of a mask or vector register.
+ if (nargs < 1) {
+ goto argerr_
+
+ } else if (argtype[argno] == MASK_ARG) {
+ # Set the default mask.
+ def_pm = v_m(argno)
+ maskno = v_i(argno)
+
+ } else if (argtype[argno] == VECTOR_ARG) {
+ # Set a vector register.
+ v_arg = argno
+ argno = argno + 1
+
+ do i = 1, PL_MAXDIM
+ if (argno <= nargs && argtype[argno] == INT_ARG) {
+ v[i] = v_i(argno)
+ argno = argno + 1
+ } else
+ v[i] = 1
+
+ call amovi (v, v_v(v_arg), PL_MAXDIM)
+ }
+
+ case KW_SHOW:
+ # Print information about a mask or vector register.
+
+ if (nargs < 1 || argtype[argno] == MASK_ARG) {
+ # Print information about a mask.
+
+ if (nargs < 1)
+ pm = def_pm
+ else {
+ pm = v_m(argno)
+ argno = argno + 1
+ }
+
+ o_fd = STDOUT
+
+ # Process option selects.
+ what = PD_SUMMARY
+ while (argno <= nargs && argtype[argno] == STRING_ARG) {
+ if (strncmp (v_s(argno), "i", 1) == 0) {
+ what = or (what, PD_INDEX)
+ } else if (strncmp (v_s(argno), "ll", 2) == 0) {
+ what = or (what, PD_LLOUT)
+ } else if (strncmp (v_s(argno), "rl", 2) == 0) {
+ what = or (what, PD_RLOUT)
+ } else if (strncmp (v_s(argno), "lh", 2) == 0) {
+ what = or (what, PD_LHDR)
+
+ } else if (v_s(argno) == '>') {
+ # Write output to a file.
+ if (v_si(argno,2) == '>') {
+ iferr (o_fd = open (v_si(argno,3),
+ APPEND, TEXT_FILE)) {
+ call erract (EA_WARN)
+ o_fd = STDOUT
+ }
+ } else {
+ iferr (o_fd = open (v_si(argno,2),
+ NEW_FILE, TEXT_FILE)) {
+ call erract (EA_WARN)
+ o_fd = STDOUT
+ }
+ }
+ } else {
+ call eprintf ("unknown option `%s'\n")
+ call pargstr (v_s(argno))
+ }
+ argno = argno + 1
+ }
+
+ # Perform the operation.
+ call pm_debug (pm, o_fd, WIDTH, what)
+ if (o_fd != STDOUT)
+ call close (o_fd)
+
+ } else if (argtype[argno] == VECTOR_ARG) {
+ # Print the value of a vector register.
+ call printf ("v%d: ")
+ call pargi (v_i(argno))
+ do i = 1, PL_MAXDIM {
+ call printf (" %d")
+ call pargi (v_vi(argno,i))
+ }
+ call printf ("\n")
+
+ } else {
+ # Print the value of all vector registers.
+ do j = 1, MAXVREG {
+ call printf ("v%d: ")
+ call pargi (j-1)
+ do i = 1, PL_MAXDIM {
+ call printf (" %d")
+ call pargi (v_reg(i,j))
+ }
+ call printf ("\n")
+ }
+ }
+
+ case KW_LOAD:
+ # Load a mask from a file.
+
+ # Get mask to be loaded.
+ pm = def_pm
+ if (nargs >= 1 && argtype[argno] == MASK_ARG) {
+ pm = v_m(argno)
+ argno = argno + 1
+ }
+
+ # Get mask filename.
+ if (argno > nargs || argtype[argno] != STRING_ARG)
+ goto argerr_
+
+ # Perform the operation.
+ if (timer)
+ call sys_mtime (time)
+ iferr (call pm_loadf (pm, v_s(argno), title, SZ_LINE))
+ call erract (EA_WARN)
+ else if (title[1] != EOS) {
+ call printf ("mask: %s\n")
+ call pargstr (title)
+ call flush (STDOUT)
+ }
+ if (timer)
+ call sys_ptime (STDOUT, "", time)
+
+ case KW_SAVE:
+ # Save a mask in a file.
+
+ # Get mask to be saved.
+ pm = def_pm
+ if (nargs >= 1 && argtype[argno] == MASK_ARG) {
+ pm = v_m(argno)
+ argno = argno + 1
+ }
+
+ # Get mask filename.
+ if (argno > nargs || argtype[argno] != STRING_ARG)
+ goto argerr_
+ else {
+ call strcpy (v_s(argno), fname, SZ_FNAME)
+ argno = argno + 1
+ }
+
+ # Get title string.
+ if (argno <= nargs && argtype[argno] == STRING_ARG) {
+ call strcpy (v_s(argno), title, SZ_LINE)
+ argno = argno + 1
+ }
+
+ # Perform the operation.
+ if (timer)
+ call sys_mtime (time)
+ iferr (call pm_savef (pm, fname, title, 0))
+ call erract (EA_WARN)
+ if (timer)
+ call sys_ptime (STDOUT, "", time)
+
+ case KW_LOADIM:
+ # Load a mask from an image.
+
+ # Get mask to be loaded.
+ pm = def_pm
+ if (nargs >= 1 && argtype[argno] == MASK_ARG) {
+ pm = v_m(argno)
+ argno = argno + 1
+ }
+
+ # Get image section.
+ if (argno > nargs || argtype[argno] != STRING_ARG)
+ goto argerr_
+
+ # Perform the operation.
+ if (timer)
+ call sys_mtime (time)
+ iferr (call pm_loadim (pm, v_s(argno), title, 0))
+ call erract (EA_WARN)
+ if (timer)
+ call sys_ptime (STDOUT, "", time)
+
+ case KW_SAVEIM:
+ # Save a mask in an image.
+
+ # Get mask to be saved.
+ pm = def_pm
+ if (nargs >= 1 && argtype[argno] == MASK_ARG) {
+ pm = v_m(argno)
+ argno = argno + 1
+ }
+
+ # Get output image name.
+ if (argno > nargs || argtype[argno] != STRING_ARG)
+ goto argerr_
+ else {
+ call strcpy (v_s(argno), fname, SZ_FNAME)
+ argno = argno + 1
+ }
+
+ # Get title string.
+ if (argno <= nargs && argtype[argno] == STRING_ARG) {
+ call strcpy (v_s(argno), title, SZ_LINE)
+ argno = argno + 1
+ }
+
+ # Perform the operation.
+ if (timer)
+ call sys_mtime (time)
+ iferr (call pm_saveim (pm, fname, title, 0))
+ call erract (EA_WARN)
+ if (timer)
+ call sys_ptime (STDOUT, "", time)
+
+ case KW_ROP:
+ # General rasterop operation.
+
+ # Get source mask.
+ pm_src = def_pm
+ if (argtype[argno] == MASK_ARG) {
+ pm_src = v_m(argno)
+ argno = argno + 1
+ }
+
+ # Get start vector in source mask.
+ if (argtype[argno] == VECTOR_ARG) {
+ call amovi (v_v(argno), v1, PL_MAXDIM)
+ argno = argno + 1
+ } else
+ call amovki (1, v1, PL_MAXDIM)
+
+ # Get destination mask.
+ pm_dst = def_pm
+ if (nargs >= 1 && argtype[argno] == MASK_ARG) {
+ pm_dst = v_m(argno)
+ argno = argno + 1
+ }
+
+ # Get start vector in destination mask.
+ if (argtype[argno] == VECTOR_ARG) {
+ call amovi (v_v(argno), v2, PL_MAXDIM)
+ argno = argno + 1
+ } else
+ call amovki (1, v2, PL_MAXDIM)
+
+ # Get vector defining size of region to be modified.
+ if (argtype[argno] == VECTOR_ARG) {
+ call amovi (v_v(argno), v3, PL_MAXDIM)
+ argno = argno + 1
+ } else
+ call amovi (PL_AXLEN(pm_dst,1), v3, PL_MAXDIM)
+
+ # Get rop.
+ if (argno <= nargs) {
+ if (argtype[argno] != INT_ARG)
+ goto argerr_
+ rop = v_i(argno); argno = argno + 1
+ } else
+ rop = PIX_SRC
+
+ # Perform the operation.
+ if (timer)
+ call sys_mtime (time)
+ call pm_rop (pm_src, v1, pm_dst, v2, v3, rop)
+ if (timer)
+ call sys_ptime (STDOUT, "", time)
+
+ case KW_STENCIL:
+ # Rasterop operation though a stencil mask.
+
+ # Get source mask.
+ pm_src = def_pm
+ if (nargs >= 1 && argtype[argno] == MASK_ARG) {
+ pm_src = v_m(argno)
+ argno = argno + 1
+ }
+
+ # Get start vector in source mask.
+ if (argtype[argno] == VECTOR_ARG) {
+ call amovi (v_v(argno), v1, PL_MAXDIM)
+ argno = argno + 1
+ } else
+ call amovki (1, v1, PL_MAXDIM)
+
+ # Get destination mask.
+ pm_dst = def_pm
+ if (nargs >= 1 && argtype[argno] == MASK_ARG) {
+ pm_dst = v_m(argno)
+ argno = argno + 1
+ }
+
+ # Get start vector in destination mask.
+ if (argtype[argno] == VECTOR_ARG) {
+ call amovi (v_v(argno), v2, PL_MAXDIM)
+ argno = argno + 1
+ } else
+ call amovki (1, v2, PL_MAXDIM)
+
+ # Get stencil mask.
+ pm_stn = def_pm
+ if (nargs >= 1 && argtype[argno] == MASK_ARG) {
+ pm_stn = v_m(argno)
+ argno = argno + 1
+ }
+
+ # Get start vector in stencil mask.
+ if (argtype[argno] == VECTOR_ARG) {
+ call amovi (v_v(argno), v3, PL_MAXDIM)
+ argno = argno + 1
+ } else
+ call amovki (1, v3, PL_MAXDIM)
+
+ # Get vector defining size of region to be modified.
+ if (argtype[argno] == VECTOR_ARG) {
+ call amovi (v_v(argno), v4, PL_MAXDIM)
+ argno = argno + 1
+ } else
+ call amovi (PL_AXLEN(pm_dst,1), v4, PL_MAXDIM)
+
+ # Get rop.
+ if (argno <= nargs) {
+ if (argtype[argno] != INT_ARG)
+ goto argerr_
+ rop = v_i(argno); argno = argno + 1
+ } else {
+ call eprintf ("no rop specified - copying src to dst\n")
+ rop = PIX_SRC
+ }
+
+ # Perform the operation.
+ if (timer)
+ call sys_mtime (time)
+ call pm_stencil (pm_src, v1, pm_dst, v2, pm_stn, v3, v4, rop)
+ if (timer)
+ call sys_ptime (STDOUT, "", time)
+
+ case KW_PTEST, KW_RTEST:
+ # Line list to pixel array or range list conversion test.
+ if (nargs < 2)
+ goto argerr_
+
+ # Get mask 1.
+ if (argtype[argno] == MASK_ARG) {
+ pm_1 = v_m(argno)
+ argno = argno + 1
+ } else
+ goto argerr_
+
+ # Get mask 2.
+ if (argtype[argno] == MASK_ARG) {
+ pm_2 = v_m(argno)
+ argno = argno + 1
+ } else
+ goto argerr_
+
+ # Perform the operation.
+ if (timer)
+ call sys_mtime (time)
+ call conv_test (pm_1, pm_2, STDOUT, opcode)
+ if (timer)
+ call sys_ptime (STDOUT, "", time)
+
+ case KW_TIMER:
+ if (timer) {
+ call printf ("timer off\n")
+ timer = false
+ } else {
+ call printf ("timer on\n")
+ timer = true
+ }
+
+ default:
+ # Unrecognized command.
+ call eprintf ("unknown switch\007\n")
+ call flush (STDERR)
+ }
+
+ call flush (STDOUT)
+ next
+argerr_
+ call eprintf ("invalid argument list\n")
+ }
+
+ do i = 1, MAXMREG
+ call pm_close (v_mask[i])
+end
+
+
+# PARSE_ARGS -- Parse the argument list to an interpreter command, leaving
+# the decoded arguments in the interpreter common, and returning the number
+# of arguments as the function value.
+
+procedure parse_args (args, ip)
+
+char args[ARB] # argument list
+int ip # pointer into argument list
+
+double dval
+int nchars, junk, i
+int ctowrd(), stridx(), gctod(), strlen()
+
+char sbuf[SZ_SBUF]
+int v_mask[MAXMREG], v_reg[PL_MAXDIM,MAXVREG]
+int nargs, argno, argtype[MAXARGS], argval[MAXARGS], s_op
+common /pmzcom/ v_mask, v_reg, nargs, argno, argtype, argval, s_op, sbuf
+
+begin
+ s_op = 1
+ argno = 1
+ nargs = 0
+
+ do i = 1, MAXARGS
+ argtype[i] = 0
+
+ # Get next token.
+ junk = ctowrd (args, ip, sbuf[s_op], SZ_SBUF-s_op)
+ nchars = strlen (sbuf[s_op])
+
+ while (nchars > 0) {
+ nargs = nargs + 1
+ if (nargs > MAXARGS)
+ call error (1, "too many arguments")
+
+ if (nchars == 1 && sbuf[s_op] == '=') {
+ # Discard assignment operator.
+ nargs = nargs - 1
+
+ } else if (nchars == 1 && stridx (sbuf[s_op], "abcd") > 0) {
+ # Mask register.
+ argval[nargs] = stridx (sbuf[s_op], "abcd")
+ argtype[nargs] = MASK_ARG
+
+ } else if (nchars == 2 && sbuf[s_op] == 'v' &&
+ # Vector register.
+ IS_DIGIT(sbuf[s_op+1])) {
+ argval[nargs] = TO_INTEG(sbuf[s_op+1])
+ argtype[nargs] = VECTOR_ARG
+
+ } else if (IS_DIGIT (sbuf[s_op])) {
+ # Get an integer constant.
+ i=1; nchars = gctod (sbuf[s_op], i, dval)
+ argval[nargs] = nint(dval)
+ argtype[nargs] = INT_ARG
+
+ # Handle the notation "opcode+value", for rasterops.
+ if (sbuf[s_op+i-1] == '+') {
+ i=i+1; nchars = gctod (sbuf[s_op], i, dval)
+ argval[nargs] = argval[nargs] + PIX_VALUE(nint(dval))
+ }
+
+ } else {
+ # String constant.
+ argval[nargs] = s_op
+ argtype[nargs] = STRING_ARG
+ s_op = s_op + nchars + 1
+ }
+
+ while (IS_WHITE(args[ip]))
+ ip = ip + 1
+ if (args[ip] == ';' || args[ip] == '\n') {
+ ip = ip + 1
+ break
+ }
+
+ # Get next token.
+ junk = ctowrd (args, ip, sbuf[s_op], SZ_SBUF-s_op)
+ nchars = strlen (sbuf[s_op])
+ }
+end
+
+
+# CONV_TEST -- Test the line list to pixel array or range list conversion
+# routines.
+
+procedure conv_test (pm_1, pm_2, fd, opcode)
+
+pointer pm_1 #I input mask
+pointer pm_2 #I output mask
+int fd #I output file, for reporting errors
+int opcode #I KW_[PR]TEST
+
+begin
+ call fprintf (fd, "conv_test called\n")
+end
+
+
+# PRINT_HELP -- Print the PMIO test interpreter commands help summary.
+
+procedure print_help (fd)
+
+int fd #I output file
+
+begin
+ call fprintf (fd, "help%48t# print command summary\n")
+ call fprintf (fd, "timer%48t# toggle timing of commands\n")
+ call fprintf (fd, "run fname%48t# read commands from a file\n")
+ call fprintf (fd, "clear%48t# clear the screen\n")
+ call fprintf (fd, "bye%48t# all done (also EOF)\n\n")
+ call fprintf (fd,
+ "create [mask] naxes axlen [depth]%48t# create a new mask\n")
+ call fprintf (fd, "load [mask] fname%48t# load mask from file\n")
+ call fprintf (fd, "save [mask] fname%48t# save mask in file\n")
+ call fprintf (fd, "loadim [mask] image%48t# load mask from image\n")
+ call fprintf (fd, "saveim [mask] image%48t# save mask in image\n")
+ call fprintf (fd, "erase [mask] [vs ve]%48t# erase a mask or region\n")
+ call fprintf (fd,
+ "draw [mask] [vs ve] [>ofile]%48t# draw mask or region of mask\n\n")
+ call fprintf (fd, "set [mask]%48t# set reference mask\n")
+ call fprintf (fd, "set [vector] i j k...%48t# load vector register\n")
+ call fprintf (fd, "show [vector]%48t# print vector register\n")
+ call fprintf (fd,
+"show [mask] [index] [ll] [rl] [>ofile]%48t# print debug info for a mask\n\n")
+ call fprintf (fd, "box P1 P2 rop%48t# draw a box\n")
+ call fprintf (fd, "circle P1 r rop%48t# draw a circle\n \n")
+ call fprintf (fd,
+ "line [mask] P1 P2 width rop%48t# draw a line segment\n")
+ call fprintf (fd, "point [mask] P1 rop%48t# draw a point\n")
+ call fprintf (fd, "polygon [mask] P1 ... PN rop%48t# draw a polygon\n")
+ call fprintf (fd, "rop src [vs] dst [vs] [vn] rop%48t# rasterop\n")
+ call fprintf (fd,
+ "stencil src [vs] dst [vs] stn [vs] [vn] rop%48t# stencil\n \n")
+ call fprintf (fd, "compare mask1 mask2%48t# compare two masks\n")
+ call fprintf (fd, "rtest mask1 mask2%48t# range list conversion test\n")
+ call fprintf (fd,
+ "ptest mask1 mask2%48t# pixel array conversion test\n")
+end