# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. include include # PL_R2L -- Convert a range list to a line list. The length of the output # line list is returned as the function value. int procedure pl_r2l$t (rl_src, xs, ll_dst, npix) PIXEL rl_src[3,ARB] #I input range list int xs #I starting pixel index in range list short ll_dst[ARB] #O destination line list int npix #I number of pixels to convert PIXEL hi, pv int last, xe, x1, x2, iz, op, np, nz, nr, dv, v, i define done_ 91 begin # No input pixels? nr = RL_LEN(rl_src) if (npix <= 0 || nr <= 0) return (0) # Initialize the linelist header. LL_VERSION(ll_dst) = LL_CURVERSION LL_HDRLEN(ll_dst) = LL_CURHDRLEN LL_NREFS(ll_dst) = 0 LL_SETBLEN(ll_dst,0) xe = xs + npix - 1 op = LL_CURHDRLEN + 1 iz = xs hi = 1 # Process the array of range lists. do i = RL_FIRST, nr + 1 { if (i <= nr) { # Load next range. x1 = rl_src[1,i] np = rl_src[2,i] pv = rl_src[3,i] x2 = x1 + np - 1 last = x2 # Get an inbounds range. if (x1 > xe) break else if (xs > x2) next else if (x1 < xs) x1 = xs else if (x2 > xe) x2 = xe # Go again if nothing inbounds. nz = x1 - iz np = x2 - x1 + 1 if (np <= 0) next } else if (iz < xe) { # At end of input range list, but need to output a ZN. nz = xe - iz + 1 np = 0 pv = 0 } else break # Encode an instruction to regenerate the current range I0-IP # of N data values of nonzero level PV. In the most complex case # we must update the high value and output a range of zeros, # followed by a range of NP high values. If NP is 1, we can # probably use a PN or [ID]S instruction to save space. # Change the high value? if (pv > 0) { dv = pv - hi if (dv != 0) { # Output IH or DH instruction? hi = pv if (abs(dv) > I_DATAMAX) { ll_dst[op] = M_SH + and (int(pv), I_DATAMAX) op = op + 1 ll_dst[op] = pv / I_SHIFT op = op + 1 } else { if (dv < 0) ll_dst[op] = M_DH + (-dv) else ll_dst[op] = M_IH + dv op = op + 1 # Convert to IS or DS if range is a single pixel. if (np == 1 && nz == 0) { v = ll_dst[op-1] ll_dst[op-1] = or (v, M_MOVE) goto done_ } } } } # Output range of zeros to catch up to current range? if (nz > 0) { # Output the ZN instruction. for (; nz > 0; nz = nz - (I_DATAMAX-1)) { ll_dst[op] = M_ZN + min(I_DATAMAX-1,nz) op = op + 1 } # Convert to PN if range is a single pixel. if (np == 1 && pv > 0 && x2 == last) { ll_dst[op-1] = ll_dst[op-1] + M_PN + 1 goto done_ } } # The only thing left is the HN instruction if we get here. for (; np > 0; np = np - I_DATAMAX) { ll_dst[op] = M_HN + min(I_DATAMAX,np) op = op + 1 } done_ iz = x2 + 1 } LL_SETLEN(ll_dst, op - 1) return (op - 1) end