1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
include <syserr.h>
include <plset.h>
include <plio.h>
# PL_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 pl_src=NULL is permitted.
procedure pl_rop (pl_src, vs_src, pl_dst, vs_dst, vn, rop)
pointer pl_src #I source mask or NULL
long vs_src[PL_MAXDIM] #I start vector in source mask
pointer pl_dst #I destination mask (required)
long vs_dst[PL_MAXDIM] #I start vector in destination mask
long vn[PL_MAXDIM] #I vector giving subregion size
long rop #I rasterop
bool need_src
pointer sp, ll_out, ll_src, ll_dst, ol_src, ol_dst
long v_src[PL_MAXDIM], v_dst[PL_MAXDIM]
long ve_src[PL_MAXDIM], ve_dst[PL_MAXDIM]
int plloop()
pointer pl_access()
errchk syserr, plvalid, plsslv, pl_access
begin
call plvalid (pl_dst)
need_src = R_NEED_SRC(rop)
if (need_src && pl_src == NULL)
call syserr (SYS_PLNULLSRC)
call smark (sp)
call salloc (ll_out, LL_MAXLEN(pl_dst), TY_SHORT)
# Initialize the N-dimensional loop counters.
call plsslv (pl_dst, vs_dst, vn, v_dst, ve_dst)
if (need_src)
call plsslv (pl_src, vs_src, vn, v_src, ve_src)
else
ll_src = ll_out # any valid pointer will do
# Perform the operation.
ol_dst = -1
repeat {
# Get a line from each mask. The DST linelist is required,
# even if R_NEED_DST(rop) is false, because the DST size
# parameters determine the size of the output list, and the
# rop may only apply to a portion of the DST list.
ll_dst = pl_access (pl_dst, v_dst)
if (need_src)
ll_src = pl_access (pl_src, v_src)
# Perform the rasterop operation upon one line of the mask.
# Note that if successive mask lines point to the same encoded
# line list, we only have to compute the result once.
if (ll_src != ol_src || ll_dst != ol_dst) {
call pl_linerop (Mems[ll_src], vs_src[1], PL_MAXVAL(pl_src),
Mems[ll_dst], vs_dst[1], PL_MAXVAL(pl_dst),
Mems[ll_out], vn[1], rop)
ol_src = ll_src
ol_dst = ll_dst
}
# Update the affected line of the destination mask.
call pl_update (pl_dst, v_dst, Mems[ll_out])
# If the end of the input mask is reached, rewind it and go again.
if (need_src)
if (plloop (v_src,vs_src,ve_src,PL_NAXES(pl_src)) == LOOP_DONE)
call amovi (vs_src, v_src, PL_NAXES(pl_src))
} until (plloop (v_dst, vs_dst, ve_dst, PL_NAXES(pl_dst)) == LOOP_DONE)
# Compress the mask if excessive free space has accumulated.
if (PL_NEEDCOMPRESS(pl_dst))
call pl_compress (pl_dst)
call sfree (sp)
end
|