# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. include # PL_P2L -- Convert a pixel array to a line list. The length of the list is # returned as the function value. int procedure pl_p2l$t (px_src, xs, ll_dst, npix) PIXEL px_src[ARB] #I input pixel array int xs #I starting index in pixbuf short ll_dst[ARB] #O destination line list int npix #I number of pixels to convert PIXEL hi, pv, nv, zero int xe, x1, iz, ip, op, np, nz, dv, v define done_ 91 begin # No input pixels? if (npix <= 0) return (0) xe = xs + npix - 1 op = LL_FIRST # Pack the pixel array into a line list. This is done by scanning # the pixel list for successive ranges of pixels of constant nonzero # value, where each range is described as follows: zero = 0 pv = max (zero, px_src[xs]) # pixel value of current range x1 = xs # start index of current range iz = xs # start index of range of zeros hi = 1 # current high value # Process the data array. do ip = xs, xe { if (ip < xe) { # Get the next pixel value, loop again if same as previous one. nv = max (zero, px_src[ip+1]) if (nv == pv) next # If current range is zero, loop again to get nonzero range. if (pv == 0) { pv = nv x1 = ip + 1 next } } else if (pv == 0) x1 = xe + 1 # Encode an instruction to regenerate the current range I0-IP # of N data values of nonzero level PV. In the most complex case # we must update the high value and output a range of zeros, # followed by a range of NP high values. If NP is 1, we can # probably use a PN or [ID]S instruction to save space. np = ip - x1 + 1 nz = x1 - iz # Change the high value? if (pv > 0) { dv = pv - hi if (dv != 0) { # Output IH or DH instruction? hi = pv if (abs(dv) > I_DATAMAX) { ll_dst[op] = M_SH + and (int(pv), I_DATAMAX) op = op + 1 ll_dst[op] = pv / I_SHIFT op = op + 1 } else { if (dv < 0) ll_dst[op] = M_DH + (-dv) else ll_dst[op] = M_IH + dv op = op + 1 # Convert to IS or DS if range is a single pixel. if (np == 1 && nz == 0) { v = ll_dst[op-1] ll_dst[op-1] = or (v, M_MOVE) goto done_ } } } } # Output range of zeros to catch up to current range? if (nz > 0) { # Output the ZN instruction. for (; nz > 0; nz = nz - I_DATAMAX) { ll_dst[op] = M_ZN + min(I_DATAMAX,nz) op = op + 1 } # Convert to PN if range is a single pixel. if (np == 1 && pv > 0) { ll_dst[op-1] = ll_dst[op-1] + M_PN + 1 goto done_ } } # The only thing left is the HN instruction if we get here. for (; np > 0; np = np - I_DATAMAX) { ll_dst[op] = M_HN + min(I_DATAMAX,np) op = op + 1 } done_ x1 = ip + 1 iz = x1 pv = nv } LL_LEN(ll_dst) = op - 1 return (op - 1) end