1 /**@(#)
2 **/
3 /* windex.c functions to support generic list based image index binning
4 *
5 * typedef struct windex { int type; int m, n; struct imregion region;
6 * void ***index; treat as List ***index; } Windex;
7 *
8 */
9
10 #include <math.h>
11 #include <stdio.h>
12 #include <tina/sys.h>
13 #include <tina/sysfuncs.h>
14 #include <tina/math.h>
15 #include <tina/mathfuncs.h>
16 #include <tina/vision.h>
17 #include <tina/visionfuncs.h>
18
19 void wx_add_entry(Windex * w, void *ptr, int type, int i, int j)
20 {
21 if (i < 0 || i >= w->m || j < 0 || j >= w->n)
22 return;
23
24 if (link_get_by_ref((List *) w->index[i][j], ptr) != NULL)
25 return; /* already referenced */
26 w->index[i][j] = ref_addtostart((List *) w->index[i][j], (void *) ptr, type);
27 }
28
29 void wx_rm_entry(Windex * w, void *ptr, int i, int j)
30 {
31 if (i < 0 || i >= w->m || j < 0 || j >= w->n)
32 return;
33
34 w->index[i][j] = list_rm_ref((List *) w->index[i][j], ptr, (void (*) ()) NULL);
35 }
36
37 void wx_delete_entry(Windex * w, void *entry)
38 {
39 void ***index;
40 int n, m;
41 int i, j;
42
43 if (w == NULL)
44 return;
45
46 m = w->m;
47 n = w->n;
48 index = w->index;
49
50 for (i = 0; i < m; ++i)
51 for (j = 0; j < n; ++j)
52 index[i][j] = list_rm_ref((List *) index[i][j], entry, (void (*) ()) NULL);
53 }
54
55 void wx_replace_entry(Windex * w, void *entry, List * entry_list)
56 {
57 List ***index;
58 List *copy;
59 int n, m;
60 int i, j;
61
62 if (w == NULL)
63 return;
64
65 m = w->m;
66 n = w->n;
67 index = (List ***) w->index;
68
69 for (i = 0; i < m; ++i)
70 for (j = 0; j < n; ++j)
71 {
72 if (link_get_by_ref(index[i][j], entry) != NULL)
73 {
74 index[i][j] = list_rm_ref(index[i][j], entry, (void (*) ()) NULL);
75 copy = list_copy(entry_list, (void *(*) ()) NULL, NULL);
76 index[i][j] = list_append(copy, index[i][j]);
77 }
78 }
79 }
80
81 void wx_duplicate_entry(Windex * w, void *entry1, void *entry2, int type)
82 {
83 List ***index;
84 int n, m;
85 int i, j;
86
87 if (w == NULL)
88 return;
89
90 m = w->m;
91 n = w->n;
92 index = (List ***) w->index;
93
94 for (i = 0; i < m; ++i)
95 for (j = 0; j < n; ++j)
96 if (link_get_by_ref(index[i][j], entry1) != NULL)
97 index[i][j] = ref_addtostart((List *) index[i][j], (void *) entry2, type);
98 }
99
100 static double wx_inth(Windex * w, Vec2 p, Vec2 v, int y)
101 {
102 if (w == NULL)
103 return (0.0);
104
105 y *= (w->region->uy - w->region->ly) / w->m;
106 y += (int)floor(w->region->ly - vec2_y(p));
107
108 return (vec2_x(p) + vec2_x(v) * y / vec2_y(v));
109 }
110
111 static double wx_intv(Windex * w, Vec2 p, Vec2 v, int x)
112 {
113 if (w == NULL)
114 return (0.0);
115
116 x *= (w->region->ux - w->region->lx) / w->n;
117 x += (int)floor(w->region->lx - vec2_x(p));
118
119 return (vec2_y(p) + vec2_y(v) * x / vec2_x(v));
120 }
121
122 void wx_add_str2(Tstring * str, int type, Windex * w)
123 /* string of 2d positions */
124
125 /* a suitable window index */
126 {
127 List *ptr;
128 List *start;
129 List *end;
130 Vec2 v = {Vec2_id};
131 Ipos p = {Ipos_id};
132 Ipos pnew = {Ipos_id};
133
134 if (str == NULL)
135 return;
136
137 start = str->start;
138 end = str->end;
139
140 ptr = start;
141 DD_GET_POS2(ptr, v);
142 p = wx_get_index(w, v);
143 wx_add_entry(w, (void *) str, type, ipos_y(p), ipos_x(p));
144 do
145 {
146 ptr = ptr->next;
147 DD_GET_POS2(ptr, v);
148 pnew = wx_get_index(w, v);
149 if (ipos_equal(pnew, p) == false)
150 {
151 p = pnew;
152 wx_add_entry(w, (void *) str, type, ipos_y(p), ipos_x(p));
153 }
154 }
155 while (ptr != end);
156 }
157
158 void wx_add_line(Windex * w, void *ptr, int type, Vec2 p1, Vec2 p2)
159 {
160 Vec2 v = {Vec2_id};
161 Ipos i1 = {Ipos_id};
162 Ipos i2 = {Ipos_id};
163 int m, n;
164
165 if (w == NULL)
166 return;
167
168 m = w->m;
169 n = w->n;
170 v = vec2_diff(p2, p1);
171
172 if (fabs(vec2_x(v)) > fabs(vec2_y(v))) /* horizontal */
173 {
174 int fi, li, fj, lj;
175 int i, j, inc;
176
177 if (vec2_y(v) < 0)
178 {
179 SWAP(Vec2, p1, p2)
180 /* BUG passing double AND Vec2 to vec2 */
181 /* v = vec2(-1.0, v); */
182 v = vec2(-1.0, 0.0);
183 }
184 i1 = wx_get_index(w, p1);
185 i2 = wx_get_index(w, p2);
186
187 if (i2.y < 0 || i1.y >= m)
188 return;
189
190 inc = (vec2_x(v) > 0) ? 1 : -1;
191
192 if (i1.y < 0)
193 {
194 fi = 0;
195 fj = (int)floor(wx_inth(w, p1, v, 0));
196 } else
197 {
198 fi = i1.y;
199 fj = i1.x;
200 }
201
202 if (i2.y >= m)
203 {
204 li = m;
205 lj = (int)floor(wx_inth(w, p1, v, m));
206 } else
207 {
208 li = i2.y;
209 lj = i2.x;
210 }
211
212 j = fj;
213 for (i = fi; i < li; ++i, j -= inc) /* --j to include above
214 * and below raster */
215 {
216 int nj = (int)floor(wx_inth(w, p1, v, i + 1));
217
218 if (nj > lj) /* only true on last iteration */
219 nj = lj;
220
221 for (; j <= nj; j += inc)
222 wx_add_entry(w, ptr, type, i, j);
223 }
224 } else
225 {
226 int fi, li, fj, lj;
227 int i, j, inc;
228
229 if (vec2_x(v) < 0)
230 {
231 SWAP(Vec2, p1, p2)
232 /* BUG passing double AND Vec2 to vec2 */
233 /* v = vec2(-1.0, v); */
234 v = vec2(-1.0, 0.0);
235 }
236 i1 = wx_get_index(w, p1);
237 i2 = wx_get_index(w, p2);
238
239 if (i2.x < 0 || i1.x >= n)
240 return;
241
242 inc = (vec2_y(v) > 0) ? 1 : -1;
243
244 if (i1.x < 0)
245 {
246 fj = 0;
247 fi = (int)floor(wx_intv(w, p1, v, 0));
248 } else
249 {
250 fj = i1.x;
251 fi = i1.y;
252 }
253
254 if (i2.x >= m)
255 {
256 lj = m;
257 li = (int)floor(wx_intv(w, p1, v, n));
258 } else
259 {
260 lj = i2.x;
261 li = i2.y;
262 }
263
264 i = fi;
265 for (j = fj; j < lj; ++j, i -= inc) /* --j to include above
266 * and below raster */
267 {
268 int ni = (int)floor(wx_intv(w, p1, v, j + 1));
269
270 if (ni > li) /* only true on last iteration */
271 ni = li;
272
273 for (; i <= ni; i += inc)
274 wx_add_entry(w, ptr, type, i, j);
275 }
276 }
277 }
278
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.