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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
include <plset.h>
include <plio.h>
# 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_r2ll (rl_src, xs, ll_dst, npix)
long 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
long 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
|