From fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Wed, 8 Jul 2015 20:46:52 -0400 Subject: Initial commit --- sys/plio/tf/plrropl.x | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 sys/plio/tf/plrropl.x (limited to 'sys/plio/tf/plrropl.x') diff --git a/sys/plio/tf/plrropl.x b/sys/plio/tf/plrropl.x new file mode 100644 index 00000000..ec936e09 --- /dev/null +++ b/sys/plio/tf/plrropl.x @@ -0,0 +1,195 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include +include "../plrseg.h" + +# PL_RANGEROP -- Rasterop operation between source and destination range lists. +# The indicated rasterop operation is performed upon the source and destination +# range lists, writing the result to RL_OUT, which is a copy of RL_DST except +# for the region affected by the rasterop operation (note that the destination +# range list cannot be edited in place since it may change size). + +procedure pl_rangeropl (rl_src, xs, src_maxval, + rl_dst, ds, dst_maxval, rl_out, npix, rop) + +long rl_src[3,ARB] #I source range list +int xs #I starting pixel index in src range list +int src_maxval #I max pixel value in src mask +long rl_dst[3,ARB] #I destination range list +int ds #I starting pixel index in dst range list +int dst_maxval #I max pixel value in dst mask +long rl_out[3,ARB] #O output list (edited version of rl_dst) +int npix #I number of pixels to convert +int rop #I rasterop + +bool need_src, need_dst, rop_enable +long data, src_value, v_src, v_dst, pv +int segsize, opcode, x, i, np, rn_o, p +int d_src[LEN_PLRDES], d_dst[LEN_PLRDES] + +begin + need_src = R_NEED_SRC(rop) + need_dst = R_NEED_DST(rop) + opcode = R_OPCODE(rop) + data = R_DATA(rop) + + # Pixel value to be used if input mask is boolean. + if (src_maxval == 1) { + src_value = data + if (src_value <= 0) + src_value = dst_maxval + } + + # Advance to the desired position in the source list, discarding + # the unused ranges. The point XS may lie within a range or in a + # zero area of the input line. + + if (need_src) { + x = 1 + plr_init (rl_src, d_src) + do i = 1, ARB { + np = min (plr_nleft(d_src), xs - x) + plr_getseg (rl_src, d_src, np, v_src) + x = x + np + if (x >= xs || np == 0) + break + } + } + + # Advance through both the source and destination lists, extracting + # line segments which have a constant value in each input list; the + # values for the two lists may differ. Apply the given rasterop to + # the source and destination pixel values and write each line segment + # as a range to the output list. If the ranges in the two input lists + # differ (randomly overlap) then the output list will generally be + # more fragmented, i.e., have more ranges of constant value. As each + # output range is generated compare it with the previous range to see + # if they can be joined, as applying a rasterop may cause two different + # ranges to have the same value. + + x = 1 + rn_o = RL_FIRST + segsize = ds - 1 + rop_enable = false + plr_init (rl_dst, d_dst) + + do i = 1, ARB { + # Set up for the next segment (before, in, and after the region to + # which the ROP applies), when the current segment is exhausted. + + if (segsize <= 0) + if (!rop_enable) { + # Begin processing central region. + segsize = npix + rop_enable = true + if (segsize <= 0) + next + } else { + # Begin processing final region. + segsize = ARB + rop_enable = false + } + + # Determine the length of the next output segment. This is the + # largest segment of constant value formed by the intersection of + # the two lists. If bounds checking has been properly performed + # then it should not be possible to see nleft=zero on either input + # list. Note that zeroed regions are valid data here. + + np = min (segsize, plr_nleft(d_dst)) + if (need_src && rop_enable && plr_nleft(d_src) > 0) + np = min (np, plr_nleft(d_src)) + if (np <= 0) + break + + # Get the segment value and advance the line pointers. We must + # read the DST list whether or not we will use the data, since + # the list pointer must be advanced NPIX pixels so that we may + # copy the remainder of the list after the loop. + + plr_getseg (rl_dst, d_dst, np, v_dst) + if (rop_enable) { + # Get v_src. + if (need_src) { + v_src = 0 + if (plr_nleft (d_src) > 0) + plr_getseg (rl_src, d_src, np, v_src) + + if (R_NOTSRC(rop)) { + v_src = not (v_src) + if (src_maxval != 0) + v_src = and (int(v_src), src_maxval) + } + + if (v_src != 0 && src_maxval == 1) + v_src = src_value + } + + # Get v_dst. + if (need_dst) { + if (R_NOTDST(rop)) { + v_dst = not (v_dst) + if (dst_maxval != 0) + v_dst = and (int(v_dst), dst_maxval) + } + } + + # Apply the rasterop. + switch (opcode) { + case PIX_CLR: + pv = 0 + case PIX_SET: + pv = data + case PIX_SRC, PIX_NOTSRC: + pv = v_src + case PIX_DST, PIX_NOTDST: + pv = v_dst + case PIX_SRC_AND_DST, PIX_SRC_AND_NOTDST, PIX_NOTSRC_AND_DST: + pv = and (v_src, v_dst) + case PIX_SRC_OR_DST, PIX_SRC_OR_NOTDST, PIX_NOTSRC_OR_DST: + pv = or (v_src, v_dst) + case PIX_SRC_XOR_DST: + pv = xor (v_src, v_dst) + case PIX_NOT_SRC_AND_DST: + pv = not (and (v_src, v_dst)) + case PIX_NOT_SRC_OR_DST: + pv = not (or (v_src, v_dst)) + case PIX_NOT_SRC_XOR_DST: + pv = not (xor (v_src, v_dst)) + } + + # Mask the high bits to prevent negative values, or map int + # to bool for the case of a boolean output mask. + + if (dst_maxval == 1 && pv != 0) + pv = 1 + else if (dst_maxval > 1) + pv = and (int(pv), dst_maxval) + + } else + pv = v_dst + + # Output a nonzero range. + if (pv > 0) { + p = rn_o - 1 + if (p >= RL_FIRST && + pv == rl_out[3,p] && x == rl_out[1,p] + rl_out[2,p]) { + # Merge new range with previous one. + rl_out[2,p] = rl_out[2,p] + np + } else { + rl_out[1,rn_o] = x + rl_out[2,rn_o] = np + rl_out[3,rn_o] = pv + rn_o = rn_o + 1 + } + } + + x = x + np + segsize = segsize - np + } + + # Update the range list header. + call amovl (rl_dst, rl_out, (RL_FIRST - 1) * 3) + RL_LEN(rl_out) = rn_o - 1 +end -- cgit