1 | /**************************************************************************
|
---|
2 | *
|
---|
3 | * marklist.c -- Functions managing the list of marks
|
---|
4 | * Copyright (C) 1994 Stuart Inglis
|
---|
5 | *
|
---|
6 | * This program is free software; you can redistribute it and/or modify
|
---|
7 | * it under the terms of the GNU General Public License as published by
|
---|
8 | * the Free Software Foundation; either version 2 of the License, or
|
---|
9 | * (at your option) any later version.
|
---|
10 | *
|
---|
11 | * This program is distributed in the hope that it will be useful,
|
---|
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
14 | * GNU General Public License for more details.
|
---|
15 | *
|
---|
16 | * You should have received a copy of the GNU General Public License
|
---|
17 | * along with this program; if not, write to the Free Software
|
---|
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
---|
19 | *
|
---|
20 | * $Id: marklist.c 3745 2003-02-20 21:20:24Z mdewsnip $
|
---|
21 | *
|
---|
22 | **************************************************************************/
|
---|
23 |
|
---|
24 | #include "sysfuncs.h"
|
---|
25 |
|
---|
26 | #include "marklist.h"
|
---|
27 | #include "pbmtools.h"
|
---|
28 | #include "utils.h"
|
---|
29 |
|
---|
30 | void
|
---|
31 | marktype_dump (marktype d)
|
---|
32 | {
|
---|
33 | fprintf (stderr, "symnum: %d\n", d.symnum);
|
---|
34 | fprintf (stderr, "xpos: %d, ypos: %d\n", d.xpos, d.ypos);
|
---|
35 | fprintf (stderr, "w: %d, h: %d\n", d.w, d.h);
|
---|
36 | fprintf (stderr, "xcen: %d, ycen: %d\n", d.xcen, d.ycen);
|
---|
37 | write_library_mark (stderr, d);
|
---|
38 | }
|
---|
39 |
|
---|
40 |
|
---|
41 | /* copy, including make a copy of the bitmap */
|
---|
42 | marktype
|
---|
43 | marktype_copy (marktype d)
|
---|
44 | {
|
---|
45 | marktype d2;
|
---|
46 | int i, j;
|
---|
47 |
|
---|
48 | d2 = d;
|
---|
49 | d2.bitmap = pbm_allocarray (d2.w, d2.h);
|
---|
50 | for (i = 0; i < d2.w; i++)
|
---|
51 | for (j = 0; j < d2.h; j++)
|
---|
52 | pbm_putpixel (d2.bitmap, i, j, pbm_getpixel (d.bitmap, i, j));
|
---|
53 | return d2;
|
---|
54 | }
|
---|
55 |
|
---|
56 |
|
---|
57 | float
|
---|
58 | marktype_density (marktype d)
|
---|
59 | {
|
---|
60 | return d.set / (float) (d.w * d.h);
|
---|
61 | }
|
---|
62 |
|
---|
63 |
|
---|
64 |
|
---|
65 | void
|
---|
66 | marktype_calc_centroid (marktype * b)
|
---|
67 | {
|
---|
68 | int r, c;
|
---|
69 | int count = 0;
|
---|
70 | int xtot = 0, ytot = 0;
|
---|
71 |
|
---|
72 | for (r = 0; r < b->h; r++)
|
---|
73 | for (c = 0; c < b->w; c++)
|
---|
74 | if (pbm_getpixel (b->bitmap, c, r))
|
---|
75 | {
|
---|
76 | count++;
|
---|
77 | xtot += c;
|
---|
78 | ytot += r;
|
---|
79 | }
|
---|
80 | if (count)
|
---|
81 | {
|
---|
82 | xtot /= count;
|
---|
83 | ytot /= count;
|
---|
84 | }
|
---|
85 | b->xcen = xtot;
|
---|
86 | b->ycen = ytot;
|
---|
87 | }
|
---|
88 |
|
---|
89 |
|
---|
90 |
|
---|
91 | static void
|
---|
92 | marktype_area (marktype * d)
|
---|
93 | {
|
---|
94 | int x, y;
|
---|
95 | int set = 0;
|
---|
96 |
|
---|
97 | for (y = 0; y < d->h; y++)
|
---|
98 | for (x = 0; x < d->w; x++)
|
---|
99 | if (pbm_getpixel (d->bitmap, x, y))
|
---|
100 | set++;
|
---|
101 | d->set = set;
|
---|
102 | }
|
---|
103 |
|
---|
104 |
|
---|
105 | static void
|
---|
106 | marktype_h_runs (marktype * d)
|
---|
107 | {
|
---|
108 | int x, y;
|
---|
109 | int inrun = 0, num = 0;
|
---|
110 | int foundblack = 0;
|
---|
111 |
|
---|
112 | for (y = 0; y < d->h; y++)
|
---|
113 | {
|
---|
114 | inrun = 0;
|
---|
115 | foundblack = 0;
|
---|
116 | for (x = 0; x < d->w; x++)
|
---|
117 | {
|
---|
118 | if ((!foundblack) && (pbm_getpixel (d->bitmap, x, y)))
|
---|
119 | foundblack = 1;
|
---|
120 | if ((foundblack) && (pbm_getpixel (d->bitmap, x, y) == 0))
|
---|
121 | inrun = 1;
|
---|
122 | if ((inrun) && (pbm_getpixel (d->bitmap, x, y)))
|
---|
123 | {
|
---|
124 | num++;
|
---|
125 | inrun = 0;
|
---|
126 | foundblack = 0;
|
---|
127 | }
|
---|
128 | }
|
---|
129 | }
|
---|
130 | d->h_runs = num;
|
---|
131 | }
|
---|
132 |
|
---|
133 | static void
|
---|
134 | marktype_v_runs (marktype * d)
|
---|
135 | {
|
---|
136 | int x, y;
|
---|
137 | int inrun = 0, num = 0;
|
---|
138 | int foundblack = 0;
|
---|
139 |
|
---|
140 |
|
---|
141 | for (x = 0; x < d->w; x++)
|
---|
142 | {
|
---|
143 | inrun = 0;
|
---|
144 | foundblack = 0;
|
---|
145 | for (y = 0; y < d->h; y++)
|
---|
146 | {
|
---|
147 | if ((!foundblack) && (pbm_getpixel (d->bitmap, x, y)))
|
---|
148 | foundblack = 1;
|
---|
149 | if ((foundblack) && (pbm_getpixel (d->bitmap, x, y) == 0))
|
---|
150 | inrun = 1;
|
---|
151 | if ((inrun) && (pbm_getpixel (d->bitmap, x, y)))
|
---|
152 | {
|
---|
153 | num++;
|
---|
154 | inrun = 0;
|
---|
155 | foundblack = 0;
|
---|
156 | }
|
---|
157 | }
|
---|
158 | }
|
---|
159 | d->v_runs = num;
|
---|
160 | }
|
---|
161 |
|
---|
162 |
|
---|
163 | /* assume we already have the centroid! */
|
---|
164 | static void
|
---|
165 | marktype_prog_cent (marktype * d)
|
---|
166 | {
|
---|
167 | int x, y;
|
---|
168 | int xtot = 0, ytot = 0;
|
---|
169 | int num = 0;
|
---|
170 |
|
---|
171 | xtot = ytot = num = 0;
|
---|
172 | for (x = 0; x < d->xcen; x++)
|
---|
173 | for (y = 0; y < d->ycen; y++)
|
---|
174 | if (pbm_getpixel (d->bitmap, x, y))
|
---|
175 | {
|
---|
176 | xtot += x;
|
---|
177 | ytot += y;
|
---|
178 | num++;
|
---|
179 | }
|
---|
180 | if (num == 0)
|
---|
181 | {
|
---|
182 | d->xcen1 = -1;
|
---|
183 | d->ycen1 = -1;
|
---|
184 | }
|
---|
185 | else
|
---|
186 | {
|
---|
187 | d->xcen1 = xtot / num;
|
---|
188 | d->ycen1 = ytot / num;
|
---|
189 | }
|
---|
190 |
|
---|
191 |
|
---|
192 | xtot = ytot = num = 0;
|
---|
193 | for (x = d->xcen; x < d->w; x++)
|
---|
194 | for (y = 0; y < d->ycen; y++)
|
---|
195 | if (pbm_getpixel (d->bitmap, x, y))
|
---|
196 | {
|
---|
197 | xtot += x;
|
---|
198 | ytot += y;
|
---|
199 | num++;
|
---|
200 | }
|
---|
201 | if (num == 0)
|
---|
202 | {
|
---|
203 | d->xcen2 = -1;
|
---|
204 | d->ycen2 = -1;
|
---|
205 | }
|
---|
206 | else
|
---|
207 | {
|
---|
208 | d->xcen2 = xtot / num;
|
---|
209 | d->ycen2 = ytot / num;
|
---|
210 | }
|
---|
211 |
|
---|
212 |
|
---|
213 |
|
---|
214 | xtot = ytot = num = 0;
|
---|
215 | for (x = 0; x < d->xcen; x++)
|
---|
216 | for (y = d->ycen; y < d->h; y++)
|
---|
217 | if (pbm_getpixel (d->bitmap, x, y))
|
---|
218 | {
|
---|
219 | xtot += x;
|
---|
220 | ytot += y;
|
---|
221 | num++;
|
---|
222 | }
|
---|
223 |
|
---|
224 |
|
---|
225 | if (num == 0)
|
---|
226 | {
|
---|
227 | d->xcen3 = -1;
|
---|
228 | d->ycen3 = -1;
|
---|
229 | }
|
---|
230 | else
|
---|
231 | {
|
---|
232 | d->xcen3 = xtot / num;
|
---|
233 | d->ycen3 = ytot / num;
|
---|
234 | }
|
---|
235 |
|
---|
236 | xtot = ytot = num = 0;
|
---|
237 | for (x = d->xcen; x < d->w; x++)
|
---|
238 | for (y = d->ycen; y < d->h; y++)
|
---|
239 | if (pbm_getpixel (d->bitmap, x, y))
|
---|
240 | {
|
---|
241 | xtot += x;
|
---|
242 | ytot += y;
|
---|
243 | num++;
|
---|
244 | }
|
---|
245 | if (num == 0)
|
---|
246 | {
|
---|
247 | d->xcen4 = -1;
|
---|
248 | d->ycen4 = -1;
|
---|
249 | }
|
---|
250 | else
|
---|
251 | {
|
---|
252 | d->xcen4 = xtot / num;
|
---|
253 | d->ycen4 = ytot / num;
|
---|
254 | }
|
---|
255 | }
|
---|
256 |
|
---|
257 |
|
---|
258 |
|
---|
259 | /* call this to get all features */
|
---|
260 | void
|
---|
261 | marktype_calc_features (marktype * d, char str[])
|
---|
262 | {
|
---|
263 | if (strlen (str))
|
---|
264 | strcpy (d->name, str);
|
---|
265 | marktype_calc_centroid (d);
|
---|
266 | marktype_area (d);
|
---|
267 | marktype_prog_cent (d);
|
---|
268 | marktype_h_runs (d);
|
---|
269 | marktype_v_runs (d);
|
---|
270 | }
|
---|
271 |
|
---|
272 |
|
---|
273 |
|
---|
274 |
|
---|
275 |
|
---|
276 | void
|
---|
277 | marktype_adj_bound (marktype * m)
|
---|
278 | {
|
---|
279 | int x, y, w, h;
|
---|
280 | int xpos, ypos;
|
---|
281 | int top = 0, left = 0, right = 0, bot = 0;
|
---|
282 | marktype temp;
|
---|
283 |
|
---|
284 | w = m->w;
|
---|
285 | h = m->h;
|
---|
286 | xpos = m->xpos;
|
---|
287 | ypos = m->ypos;
|
---|
288 |
|
---|
289 | for (y = 0; y < h; y++)
|
---|
290 | for (x = 0; x < w; x++)
|
---|
291 | if (pbm_getpixel (m->bitmap, x, y))
|
---|
292 | {
|
---|
293 | top = y;
|
---|
294 | x = w;
|
---|
295 | y = h;
|
---|
296 | }
|
---|
297 |
|
---|
298 | for (y = h - 1; y >= 0; y--)
|
---|
299 | for (x = 0; x < w; x++)
|
---|
300 | if (pbm_getpixel (m->bitmap, x, y))
|
---|
301 | {
|
---|
302 | bot = y;
|
---|
303 | x = w;
|
---|
304 | y = -1;
|
---|
305 | }
|
---|
306 |
|
---|
307 | for (x = 0; x < w; x++)
|
---|
308 | for (y = 0; y < h; y++)
|
---|
309 | if (pbm_getpixel (m->bitmap, x, y))
|
---|
310 | {
|
---|
311 | left = x;
|
---|
312 | x = w;
|
---|
313 | y = h;
|
---|
314 | }
|
---|
315 |
|
---|
316 | for (x = w - 1; x >= 0; x--)
|
---|
317 | for (y = 0; y < h; y++)
|
---|
318 | if (pbm_getpixel (m->bitmap, x, y))
|
---|
319 | {
|
---|
320 | right = x;
|
---|
321 | x = -1;
|
---|
322 | y = h;
|
---|
323 | }
|
---|
324 |
|
---|
325 | temp.w = right - left + 1;
|
---|
326 | temp.h = bot - top + 1;
|
---|
327 | temp.xpos = xpos + left;
|
---|
328 | temp.ypos = ypos + top;
|
---|
329 | temp.bitmap = pbm_allocarray (temp.w, temp.h);
|
---|
330 |
|
---|
331 | for (x = 0; x < temp.w; x++)
|
---|
332 | for (y = 0; y < temp.h; y++)
|
---|
333 | pbm_putpixel (temp.bitmap, x, y, pbm_getpixel (m->bitmap, x + left, y + top));
|
---|
334 |
|
---|
335 | pbm_freearray (&(m->bitmap), h);
|
---|
336 |
|
---|
337 | marktype_calc_features (&temp, "?");
|
---|
338 | *m = temp;
|
---|
339 | }
|
---|
340 |
|
---|
341 |
|
---|
342 |
|
---|
343 |
|
---|
344 |
|
---|
345 |
|
---|
346 | /* returns a newly created mark reprenting the average of the marklist */
|
---|
347 | void
|
---|
348 | marklist_average (marklistptr list, marktype * avgmark)
|
---|
349 | {
|
---|
350 | int w = 0, h = 0;
|
---|
351 | int t = INT_MAX, b = 0, l = INT_MAX, r = 0, matched = 0;
|
---|
352 | marktype d, temp;
|
---|
353 | marklistptr step;
|
---|
354 | static int a[100][100];
|
---|
355 | int x, y;
|
---|
356 |
|
---|
357 | if (list == NULL)
|
---|
358 | error_msg ("marklist_average", "Can't average 'nothing'!", "");
|
---|
359 |
|
---|
360 | for (step = list; step; step = step->next)
|
---|
361 | {
|
---|
362 | matched++;
|
---|
363 | temp = step->data;
|
---|
364 | w = max (w, temp.w);
|
---|
365 | h = max (h, temp.h);
|
---|
366 | r = max (r, temp.xcen);
|
---|
367 | l = min (l, temp.xcen);
|
---|
368 | b = max (b, temp.ycen);
|
---|
369 | t = min (t, temp.ycen);
|
---|
370 | }
|
---|
371 | w = w + (r - l);
|
---|
372 | h = h + (b - t);
|
---|
373 | if ((w >= 100) || (h >= 100))
|
---|
374 | matched = 0;
|
---|
375 |
|
---|
376 | if (matched > 1)
|
---|
377 | {
|
---|
378 | int x_off, y_off;
|
---|
379 | for (x = 0; x < w; x++)
|
---|
380 | for (y = 0; y < h; y++)
|
---|
381 | a[x][y] = 0;
|
---|
382 |
|
---|
383 | for (step = list; step; step = step->next)
|
---|
384 | {
|
---|
385 | x_off = r - step->data.xcen;
|
---|
386 | y_off = b - step->data.ycen;
|
---|
387 | for (x = 0; x < step->data.w; x++)
|
---|
388 | for (y = 0; y < step->data.h; y++)
|
---|
389 | if (pbm_getpixel (step->data.bitmap, x, y))
|
---|
390 | a[x + x_off][y + y_off]++;
|
---|
391 | }
|
---|
392 |
|
---|
393 | d.w = w;
|
---|
394 | d.h = h;
|
---|
395 | d.bitmap = pbm_allocarray (w, h);
|
---|
396 | for (x = 0; x < w; x++)
|
---|
397 | for (y = 0; y < h; y++)
|
---|
398 | if (a[x][y] > max (1, (matched / 2))) /* > gives better CR than >= */
|
---|
399 | pbm_putpixel (d.bitmap, x, y, 1);
|
---|
400 | marktype_adj_bound (&d);
|
---|
401 | strcpy (d.name, "?");
|
---|
402 | marktype_calc_centroid (&d);
|
---|
403 | }
|
---|
404 | else
|
---|
405 | d = marktype_copy (list->data);
|
---|
406 |
|
---|
407 | *avgmark = d;
|
---|
408 | }
|
---|
409 |
|
---|
410 |
|
---|
411 |
|
---|
412 |
|
---|
413 |
|
---|
414 |
|
---|
415 | void
|
---|
416 | marklist_setnull (marklistptr * list)
|
---|
417 | {
|
---|
418 | *list = NULL;
|
---|
419 | }
|
---|
420 |
|
---|
421 |
|
---|
422 | marklistptr
|
---|
423 | marklist_add (marklistptr * list, marktype m)
|
---|
424 | {
|
---|
425 | marklistptr p;
|
---|
426 |
|
---|
427 | if (*list == NULL)
|
---|
428 | {
|
---|
429 | *list = (marklistptr) malloc (sizeof (marklisttype));
|
---|
430 | if ((*list) == NULL)
|
---|
431 | error_msg ("marklist_add", "OUT of Memory in marklist_add", "");
|
---|
432 | p = *list;
|
---|
433 | }
|
---|
434 | else
|
---|
435 | {
|
---|
436 | p = *list;
|
---|
437 | while (p->next != NULL)
|
---|
438 | p = p->next;
|
---|
439 | p->next = (marklistptr) malloc (sizeof (marklisttype));
|
---|
440 | if (p->next == NULL)
|
---|
441 | error_msg ("marklist_add", "OUT of Memory in marklist_add", "");
|
---|
442 | p = p->next;
|
---|
443 | }
|
---|
444 | p->data = m;
|
---|
445 | p->next = NULL;
|
---|
446 | return p;
|
---|
447 |
|
---|
448 | }
|
---|
449 |
|
---|
450 |
|
---|
451 |
|
---|
452 | marklistptr
|
---|
453 | marklist_addcopy (marklistptr * list, marktype m)
|
---|
454 | {
|
---|
455 | marktype d;
|
---|
456 |
|
---|
457 | d = marktype_copy (m);
|
---|
458 | return marklist_add (list, d);
|
---|
459 | }
|
---|
460 |
|
---|
461 |
|
---|
462 |
|
---|
463 | int
|
---|
464 | marklist_length (marklistptr list)
|
---|
465 | {
|
---|
466 | int count = 0;
|
---|
467 |
|
---|
468 | while (list)
|
---|
469 | {
|
---|
470 | count++;
|
---|
471 | list = list->next;
|
---|
472 | }
|
---|
473 | return count;
|
---|
474 | }
|
---|
475 |
|
---|
476 |
|
---|
477 |
|
---|
478 |
|
---|
479 |
|
---|
480 | void
|
---|
481 | marklist_dump (marklistptr list)
|
---|
482 | {
|
---|
483 | int count = 0;
|
---|
484 | marktype d;
|
---|
485 |
|
---|
486 | while (list)
|
---|
487 | {
|
---|
488 | d = list->data;
|
---|
489 | marktype_dump (d);
|
---|
490 |
|
---|
491 | count++;
|
---|
492 | list = list->next;
|
---|
493 | }
|
---|
494 | }
|
---|
495 |
|
---|
496 |
|
---|
497 |
|
---|
498 |
|
---|
499 | /* pos starts from 0, to up marklist_length-1 */
|
---|
500 | marklistptr
|
---|
501 | marklist_getat (marklistptr list, int pos, marktype * d)
|
---|
502 | {
|
---|
503 | int count = 0;
|
---|
504 |
|
---|
505 | while (list)
|
---|
506 | {
|
---|
507 | if (count == pos)
|
---|
508 | {
|
---|
509 | *d = list->data;
|
---|
510 | return list;
|
---|
511 | }
|
---|
512 | count++;
|
---|
513 | list = list->next;
|
---|
514 | }
|
---|
515 | fprintf (stderr, "marklist_getat(): access off ends of list: pos %d\n", pos);
|
---|
516 | return NULL;
|
---|
517 | }
|
---|
518 |
|
---|
519 |
|
---|
520 |
|
---|
521 | void
|
---|
522 | marklist_free (marklistptr * list)
|
---|
523 | {
|
---|
524 | marklistptr n;
|
---|
525 |
|
---|
526 | while ((*list) != NULL)
|
---|
527 | {
|
---|
528 | n = (*list)->next;
|
---|
529 | pbm_freearray (&((*list)->data.bitmap), (*list)->data.h);
|
---|
530 | free ((*list));
|
---|
531 | (*list) = n;
|
---|
532 | }
|
---|
533 | }
|
---|
534 |
|
---|
535 |
|
---|
536 |
|
---|
537 | int
|
---|
538 | marklist_removeat (marklistptr * list, int pos)
|
---|
539 | {
|
---|
540 | marklistptr c, n, p = NULL;
|
---|
541 | int count = 0;
|
---|
542 |
|
---|
543 | if ((pos == 0) && (*list))
|
---|
544 | { /* if removing the 1st element */
|
---|
545 | *list = (*list)->next;
|
---|
546 | return 1;
|
---|
547 | }
|
---|
548 | else
|
---|
549 | {
|
---|
550 | c = *list;
|
---|
551 | while (c)
|
---|
552 | {
|
---|
553 | if (count == pos)
|
---|
554 | { /* two cases, no previous, >=1 previous */
|
---|
555 | if (p == NULL) /* no previous */
|
---|
556 | {
|
---|
557 | n = c->next;
|
---|
558 | pbm_freearray (&c->data.bitmap, c->data.h);
|
---|
559 | free (c);
|
---|
560 | c = n;
|
---|
561 | return 1;
|
---|
562 | }
|
---|
563 | else
|
---|
564 | /* >=1 previous */
|
---|
565 | {
|
---|
566 | n = c->next;
|
---|
567 | pbm_freearray (&c->data.bitmap, c->data.h);
|
---|
568 | free (c);
|
---|
569 | p->next = n;
|
---|
570 | return 1;
|
---|
571 | }
|
---|
572 | }
|
---|
573 | count++;
|
---|
574 | p = c;
|
---|
575 | c = c->next;
|
---|
576 | }
|
---|
577 | }
|
---|
578 | fprintf (stderr, "marklist_removeat(): access off ends of list: pos %d\n", pos);
|
---|
579 | return 0; /* nothing was removed */
|
---|
580 | }
|
---|
581 |
|
---|
582 |
|
---|
583 |
|
---|
584 | marklistptr
|
---|
585 | marklist_next (marklistptr list)
|
---|
586 | {
|
---|
587 | return list->next;
|
---|
588 | }
|
---|
589 |
|
---|
590 |
|
---|
591 | /* only writes out ascii form */
|
---|
592 | void
|
---|
593 | write_library_mark (FILE * fp, marktype d)
|
---|
594 | {
|
---|
595 | int r, c, rows, cols;
|
---|
596 | int xtot = d.xcen, ytot = d.ycen;
|
---|
597 |
|
---|
598 | rows = d.h;
|
---|
599 | cols = d.w;
|
---|
600 |
|
---|
601 | fprintf (fp, "Mark: %d\n", d.symnum);
|
---|
602 | fprintf (fp, "Char: %s\n", d.name);
|
---|
603 | fprintf (fp, "Cols: %d Rows: %d\n", d.w, d.h);
|
---|
604 | for (r = 0; r < d.h; r++)
|
---|
605 | {
|
---|
606 | for (c = 0; c < d.w; c++)
|
---|
607 | if ((r == ytot) && (c == xtot))
|
---|
608 | putc (pbm_getpixel (d.bitmap, c, r) ? 'C' : '!', fp);
|
---|
609 | else
|
---|
610 | putc (pbm_getpixel (d.bitmap, c, r) ? 'X' : '.', fp);
|
---|
611 | putc ('\n', fp);
|
---|
612 | }
|
---|
613 | }
|
---|
614 |
|
---|
615 |
|
---|
616 |
|
---|
617 | /* only reads in ascii library */
|
---|
618 | int
|
---|
619 | read_library_mark (FILE * fp, marktype * d)
|
---|
620 | {
|
---|
621 | int r, c, rows, cols, numread, ch1 = 'C';
|
---|
622 | char str1[100], str2[100];
|
---|
623 |
|
---|
624 | numread = fscanf (fp, "%s %d\n", str1, &(d->symnum));
|
---|
625 | if ((numread != 2) || (strcmp (str1, "Mark:") != 0))
|
---|
626 | return 0;
|
---|
627 | fscanf (fp, "%s %s\n", str1, (d->name));
|
---|
628 | fscanf (fp, "%s %d %s %d\n", str1, &(d->w), str2, &(d->h));
|
---|
629 | cols = d->w;
|
---|
630 | rows = d->h;
|
---|
631 | d->bitmap = pbm_allocarray (cols, rows);
|
---|
632 | for (r = 0; r < rows; r++)
|
---|
633 | {
|
---|
634 | for (c = 0; c < cols; c++)
|
---|
635 | {
|
---|
636 | ch1 = getc (fp);
|
---|
637 | if ((ch1 == 'X') || (ch1 == 'C'))
|
---|
638 | pbm_putpixel (d->bitmap, c, r, 1);
|
---|
639 | else
|
---|
640 | pbm_putpixel (d->bitmap, c, r, 0);
|
---|
641 | }
|
---|
642 | ch1 = getc (fp);
|
---|
643 | }
|
---|
644 | marktype_calc_features (d, "?");
|
---|
645 |
|
---|
646 | return 1;
|
---|
647 | }
|
---|
648 |
|
---|
649 |
|
---|
650 |
|
---|
651 |
|
---|
652 |
|
---|
653 |
|
---|
654 |
|
---|
655 | int
|
---|
656 | read_library (char libraryname[], marklistptr * library)
|
---|
657 | {
|
---|
658 | int err, count;
|
---|
659 | FILE *lib;
|
---|
660 | marktype d;
|
---|
661 | marklistptr step;
|
---|
662 |
|
---|
663 | lib = fopen (libraryname, "rb");
|
---|
664 | if (lib == NULL)
|
---|
665 | error_msg ("read_library()", "Trouble opening library file", "");
|
---|
666 | *library = NULL;
|
---|
667 | count = 0;
|
---|
668 | while (!isEOF (lib))
|
---|
669 | {
|
---|
670 | err = read_library_mark (lib, &d);
|
---|
671 | if (!err)
|
---|
672 | error_msg ("read_library()", "unknown format of the library file.", "");
|
---|
673 | d.symnum = count;
|
---|
674 | count++;
|
---|
675 | if ((*library) == NULL)
|
---|
676 | step = marklist_add (library, d);
|
---|
677 | else
|
---|
678 | step = marklist_add (&step, d);
|
---|
679 | }
|
---|
680 | count = marklist_length (*library);
|
---|
681 | fclose (lib);
|
---|
682 |
|
---|
683 | return count;
|
---|
684 | }
|
---|
685 |
|
---|
686 |
|
---|
687 |
|
---|
688 |
|
---|
689 |
|
---|
690 |
|
---|
691 | /**********************************************************************
|
---|
692 |
|
---|
693 | 'elem' routines for coding offsets
|
---|
694 |
|
---|
695 | the elem datatype contains the 3 params for arithmetic coding,
|
---|
696 | stored as a no-duplicates order linked list.
|
---|
697 |
|
---|
698 | ************************************************************************/
|
---|
699 |
|
---|
700 |
|
---|
701 |
|
---|
702 |
|
---|
703 | void
|
---|
704 | elem_add (elemlist * list, int num)
|
---|
705 | {
|
---|
706 | elemptr temp, nn;
|
---|
707 | int p, f;
|
---|
708 |
|
---|
709 | list->tot++;
|
---|
710 | if (list->head == NULL)
|
---|
711 | {
|
---|
712 | list->head = (elemptr) malloc (sizeof (elem));
|
---|
713 | if ((list->head) == NULL)
|
---|
714 | error_msg ("", "ekk", "");
|
---|
715 | temp = list->head;
|
---|
716 | temp->next = NULL;
|
---|
717 | temp->num = num;
|
---|
718 | temp->pos = 0;
|
---|
719 | temp->freq = 1;
|
---|
720 | }
|
---|
721 | else
|
---|
722 | { /* add to list */
|
---|
723 | temp = list->head;
|
---|
724 | p = 0;
|
---|
725 | f = 0;
|
---|
726 | while ((num > temp->num) && (temp->next != NULL))
|
---|
727 | {
|
---|
728 | p = temp->pos;
|
---|
729 | f = temp->freq;
|
---|
730 | temp = temp->next;
|
---|
731 | }
|
---|
732 |
|
---|
733 | if (temp->num == num)
|
---|
734 | temp->freq++;
|
---|
735 | else
|
---|
736 | { /* insert it */
|
---|
737 | nn = (elemptr) malloc (sizeof (elem));
|
---|
738 | if (nn == NULL)
|
---|
739 | error_msg ("", "ekk", "");
|
---|
740 |
|
---|
741 | if (num < temp->num)
|
---|
742 | {
|
---|
743 | nn->num = temp->num;
|
---|
744 | nn->pos = temp->pos;
|
---|
745 | nn->freq = temp->freq;
|
---|
746 | nn->next = temp->next;
|
---|
747 | temp->num = num;
|
---|
748 | temp->pos = p + f;
|
---|
749 | temp->freq = 1;
|
---|
750 | temp->next = nn;
|
---|
751 | }
|
---|
752 | else
|
---|
753 | {
|
---|
754 | nn->next = temp->next;
|
---|
755 | temp->next = nn;
|
---|
756 | nn->pos = temp->pos + temp->freq;
|
---|
757 | nn->num = num;
|
---|
758 | nn->freq = 1;
|
---|
759 | temp = nn;
|
---|
760 | }
|
---|
761 | }
|
---|
762 | }
|
---|
763 | /* update frequencies */
|
---|
764 | temp = temp->next;
|
---|
765 | if (temp)
|
---|
766 | do
|
---|
767 | {
|
---|
768 | temp->pos++;
|
---|
769 | temp = temp->next;
|
---|
770 | }
|
---|
771 | while (temp);
|
---|
772 | }
|
---|
773 |
|
---|
774 |
|
---|
775 | void
|
---|
776 | elem_free (elemlist * list)
|
---|
777 | {
|
---|
778 | elemptr n, p;
|
---|
779 |
|
---|
780 | p = list->head;
|
---|
781 | while (p != NULL)
|
---|
782 | {
|
---|
783 | n = p->next;
|
---|
784 | free (p);
|
---|
785 | p = n;
|
---|
786 | }
|
---|
787 | list->head = NULL;
|
---|
788 | }
|
---|
789 |
|
---|
790 | int
|
---|
791 | elem_find (elemlist * list, int n, int *p, int *f, int *t)
|
---|
792 | {
|
---|
793 | elemptr temp;
|
---|
794 |
|
---|
795 | temp = list->head;
|
---|
796 | while (temp)
|
---|
797 | {
|
---|
798 | if (temp->num == n)
|
---|
799 | {
|
---|
800 | *p = temp->pos;
|
---|
801 | *f = temp->freq + temp->pos;
|
---|
802 | *t = list->tot;
|
---|
803 | return 1;
|
---|
804 | }
|
---|
805 | temp = temp->next;
|
---|
806 | }
|
---|
807 | return 0;
|
---|
808 | }
|
---|
809 |
|
---|
810 |
|
---|
811 | int
|
---|
812 | elem_getrange (elemlist * list, int range, int *num)
|
---|
813 | {
|
---|
814 | elemptr temp;
|
---|
815 |
|
---|
816 | temp = list->head;
|
---|
817 | while (temp)
|
---|
818 | {
|
---|
819 | if ((range >= temp->pos) && (range < (temp->pos + temp->freq)))
|
---|
820 | {
|
---|
821 | *num = temp->num;
|
---|
822 | return 1;
|
---|
823 | }
|
---|
824 | temp = temp->next;
|
---|
825 | }
|
---|
826 | return 0;
|
---|
827 | }
|
---|