1 /**********
2 *
3 * Copyright (c) 2003, Division of Imaging Science and Biomedical Engineering,
4 * University of Manchester, UK. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without modification,
7 * are permitted provided that the following conditions are met:
8 *
9 * . Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * . Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
15 *
16 * . Neither the name of the University of Manchester nor the names of its
17 * contributors may be used to endorse or promote products derived from this
18 * software without specific prior written permission.
19 *
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 **********
34 *
35 * Program : TINA
36 * File : $Source: /home/tina/cvs/tina-libs/tina/sys/sysLst_strings.c,v $
37 * Date : $Date: 2008/12/02 22:03:07 $
38 * Version : $Revision: 1.5 $
39 * CVS Id : $Id: sysLst_strings.c,v 1.5 2008/12/02 22:03:07 paul Exp $
40 *
41 * Notes :
42 *
43 * Tstring handling (Tstring is generic list).
44 * Tstring is {int type; List *start; List *end; int count; Listprops;}
45 * Tstring represents and manipulates connected data (eg derived from
46 * edges) as a whole. Tstring handling functions are prefixed str.
47 *
48 *********
49 */
50
51 #include "sysLst_strings.h"
52
53 #if HAVE_CONFIG_H
54 #include <config.h>
55 #endif
56
57 #include <stdio.h>
58 #include <tina/sys/sys_LstDef.h>
59 #include <tina/sys/sys_MemDef.h>
60 #include <tina/sys/sysLst_list.h>
61 #include <tina/sys/sysLst_prop.h>
62 #include <tina/sys/sysLst_strings.h>
63 #include <tina/sys/sysLst_ddstr.h>
64 #include <tina/sys/sysMem_ralloc.h>
65 #include <tina/sys/sysGen_error.h>
66
67
68 Tstring *str_alloc(void)
69 {
70 /* allocate string structure and initialise pointers to nil */
71 Tstring *str = ts_ralloc(Tstring);
72 str->count = str->type = 0;
73 str->start = str->end = (List *) NULL;
74 str->props = NULL;
75 return (str);
76 }
77
78 Tstring *str_make(int type, List * start, List * end)
79 {
80 Tstring *str = ts_ralloc(Tstring);
81 str->type = type;
82 str->start = start;
83 str->end = end;
84 if (type == LOOP)
85 {
86 start->last = end;
87 end->next = start;
88 }
89 str->count = ddstr_count(start, end);
90 str->props = NULL;
91 return (str);
92 }
93
94 List *str_mid_point(Tstring * str)
95 {
96 List *ddstr_nth_point();
97 if (str == NULL)
98 return (NULL);
99 return (ddstr_nth_point(str->start, str->end, str->count / 2));
100 }
101
102 /* copy of n evenly spaced points along a string */
103
104 Tstring *str_divide(Tstring * str, int n)
105 {
106 Tstring *new = str_alloc();
107 List *ddnew = (List *) dd_list_make(n, 0);
108 List *dd1, *dd2;
109 int i, j, l;
110 double dl;
111
112 new->type = str->type;
113 new->start = ddnew;
114 new->end = dd_get_end(ddnew);
115 new->count = n;
116
117 l = str->count;
118 switch (str->type)
119 {
120 case STRING:
121 dl = (l - 1) / (n - 1);
122 break;
123 case LOOP:
124 dl = (l - 1) / n;
125 new->end->next = new->start;
126 new->start->last = new->end;
127 break;
128
129 default:
130 dl = 0.0;
131 error ("str_divide: unknown type", fatal);
132 }
133
134 for (i = 0, j = 0, dd1 = str->start, dd2 = ddnew;
135 j < n; i++, dd1 = dd1->next, dd2 = dd2->next)
136 {
137 if (i >= j * dl || (str->type == STRING && dd1 == str->end))
138 {
139 dd2->type = dd1->type;
140 dd2->to = dd1->to;
141 j++;
142 }
143 }
144
145 return (new);
146 }
147
148 void str_free(Tstring * str, void (*freefunc) ( /* ??? */ ))
149 {
150 void ddstr_free();
151
152 if (str == NULL)
153 return;
154
155 proplist_freelist(str->props);
156 ddstr_free(str->start, str->end, freefunc);
157 rfree((void *) str);
158 }
159
160 void str_rm_links(Tstring * str)
161 {
162 void ddstr_rm_links();
163
164 if (str == NULL)
165 return;
166
167 proplist_freelist(str->props);
168 ddstr_rm_links(str->start, str->end);
169 rfree((void *) str);
170 }
171
172 void str_rm(Tstring * str, void (*freefunc) ( /* ??? */ ))
173 {
174 void ddstr_rm();
175
176 if (str == NULL)
177 return;
178
179 proplist_freelist(str->props);
180 ddstr_rm(str->start, str->end, freefunc);
181 rfree((void *) str);
182 }
183
184 void str_rm_only_str(Tstring * str)
185 {
186 if (str == NULL)
187 return;
188
189 proplist_freelist(str->props);
190 rfree((void *) str);
191 }
192
193 Tstring *str_segment(Tstring * str, List * at)
194 {
195 List *start;
196 List *end;
197
198 if (str == NULL)
199 return (NULL);
200
201 start = str->start;
202 end = str->end;
203
204 if (at == start || at == end)
205 return (NULL);
206
207 str->end = at;
208 str->count = ddstr_count(start, at);
209 return (str_make(str->type, at->next, end));
210 }
211
212 List *str_link_get_by_ref(Tstring * str, void *ptr)
213 {
214 List *ddstr_link_get_by_ref();
215
216 if (str == NULL)
217 return (NULL);
218
219 return (ddstr_link_get_by_ref(str->start, str->end, ptr));
220 }
221
222 Tstring *str_list_get_by_ref(List * strings, void *ptr)
223 {
224 List *lptr;
225
226 for (lptr = strings; lptr != NULL; lptr = lptr->next)
227 if (str_link_get_by_ref((Tstring *) lptr->to, ptr) != NULL)
228 return ((Tstring *) lptr->to);
229 return (NULL);
230 }
231
232 void str_reverse(Tstring * str)
233 {
234 void ddstr_reverse();
235 if (str == NULL)
236 return;
237 ddstr_reverse(&(str->start), &(str->end));
238 if (str->type == LOOP)
239 {
240 str->start->last = str->end;
241 str->end->next = str->start;
242 }
243 }
244
245 Tstring *str_combine(Tstring * s1, Tstring * s2)
246 {
247 if (s1 == NULL || s2 == NULL)
248 return (NULL);
249
250 s1->end->next = s2->start;
251 s2->start->last = s1->end;
252 return (str_make(s1->type, s1->start, s2->end));
253 }
254
255 Tstring *str_copy(Tstring * str, void *(*copyfunc) ( /* ??? */ ),
256 void *data)
257 {
258 Tstring *copy;
259 List *start;
260 List *end;
261 void ddstr_copy();
262
263 if (str == NULL)
264 return (NULL);
265
266 start = str->start;
267 end = str->end;
268 ddstr_copy(&start, &end, copyfunc, data);
269 copy = str_make(str->type, start, end);
270 copy->props = proplist_copy(str->props);
271 return (copy);
272 }
273
274 Tstring *str_clone(Tstring * str) /* new string pointing at old
275 * * data */
276 {
277 Tstring *copy;
278 List *start;
279 List *end;
280
281 if (str == NULL)
282 return (NULL);
283
284 start = str->start;
285 end = str->end;
286
287 ddstr_copy(&start, &end, (void *(*)()) NULL, NULL);
288 if (str->start->last == str->end)
289 {
290 start->last = end;
291 end->next = start;
292 }
293 copy = str_make(str->type, start, end);
294 copy->props = proplist_copy(str->props);
295 return (copy);
296 }
297
298 void str_apply_func(Tstring * str, void (*func) ( /* ??? */ ), void *data)
299 {
300 void ddstr_apply_func();
301
302 if (str == NULL)
303 return;
304
305 ddstr_apply_func(str->start, str->end, func, data);
306 }
307
308 List *str_get_min(Tstring * str, Bool(*func) ( /* ??? */ ), void *data)
309 {
310 List *ddstr_get_min();
311 List *ddlist = NULL;
312
313 if (str)
314 {
315 ddlist = ddstr_get_min(str->start, str->end, func, data);
316 }
317 return ddlist;
318 }
319
320 Bool str_get_min_dist(Tstring * str, Bool(*func) ( /* ??? */ ), void *data,
321 double *d)
322 {
323 List *min_ptr = str_get_min(str, func, data);
324
325 return (func(min_ptr->to, min_ptr->type, data, d));
326 }
327
328 Tstring *str_list_get_min(List * strings, Bool(*func) ( /* ??? */ ),
329 void *data)
330 {
331 List *ptr;
332 Tstring *min_str = NULL;
333 double d, min_d = 0.0;
334
335 for (ptr = strings; ptr != NULL; ptr = ptr->next)
336 {
337 if (str_get_min_dist((Tstring *) ptr->to, func, data, &d) == false)
338 continue;
339
340 if (min_str == NULL || d < min_d)
341 {
342 min_str = ptr->to;
343 min_d = d;
344 }
345 }
346 return (min_str);
347 }
348
349 void str_rm_list(List * strings)
350 {
351 list_rm(strings, str_rm_links);
352 }
353
354 int str_length(Tstring * str)
355 {
356 int i;
357 List *dd;
358
359 if (str == NULL)
360 return (-1);
361
362 for (dd = str->start, i = 1;; dd = dd->next, i++)
363 if (dd == str->end)
364 break;
365
366 return (i);
367 }
368
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.