Leptonica  1.73
Image processing and image analysis suite
ptafunc2.c
Go to the documentation of this file.
1 /*====================================================================*
2  - Copyright (C) 2001 Leptonica. All rights reserved.
3  -
4  - Redistribution and use in source and binary forms, with or without
5  - modification, are permitted provided that the following conditions
6  - are met:
7  - 1. Redistributions of source code must retain the above copyright
8  - notice, this list of conditions and the following disclaimer.
9  - 2. Redistributions in binary form must reproduce the above
10  - copyright notice, this list of conditions and the following
11  - disclaimer in the documentation and/or other materials
12  - provided with the distribution.
13  -
14  - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15  - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16  - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17  - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18  - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23  - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *====================================================================*/
26 
72 #include "allheaders.h"
73 
74 
75 /*---------------------------------------------------------------------*
76  * Sorting *
77  *---------------------------------------------------------------------*/
88 PTA *
89 ptaSort(PTA *ptas,
90  l_int32 sorttype,
91  l_int32 sortorder,
92  NUMA **pnaindex)
93 {
94 PTA *ptad;
95 NUMA *naindex;
96 
97  PROCNAME("ptaSort");
98 
99  if (pnaindex) *pnaindex = NULL;
100  if (!ptas)
101  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
102  if (sorttype != L_SORT_BY_X && sorttype != L_SORT_BY_Y)
103  return (PTA *)ERROR_PTR("invalid sort type", procName, NULL);
104  if (sortorder != L_SORT_INCREASING && sortorder != L_SORT_DECREASING)
105  return (PTA *)ERROR_PTR("invalid sort order", procName, NULL);
106 
107  if (ptaGetSortIndex(ptas, sorttype, sortorder, &naindex) != 0)
108  return (PTA *)ERROR_PTR("naindex not made", procName, NULL);
109 
110  ptad = ptaSortByIndex(ptas, naindex);
111  if (pnaindex)
112  *pnaindex = naindex;
113  else
114  numaDestroy(&naindex);
115  if (!ptad)
116  return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
117  return ptad;
118 }
119 
120 
131 l_int32
133  l_int32 sorttype,
134  l_int32 sortorder,
135  NUMA **pnaindex)
136 {
137 l_int32 i, n;
138 l_float32 x, y;
139 NUMA *na;
140 
141  PROCNAME("ptaGetSortIndex");
142 
143  if (!pnaindex)
144  return ERROR_INT("&naindex not defined", procName, 1);
145  *pnaindex = NULL;
146  if (!ptas)
147  return ERROR_INT("ptas not defined", procName, 1);
148  if (sorttype != L_SORT_BY_X && sorttype != L_SORT_BY_Y)
149  return ERROR_INT("invalid sort type", procName, 1);
150  if (sortorder != L_SORT_INCREASING && sortorder != L_SORT_DECREASING)
151  return ERROR_INT("invalid sort order", procName, 1);
152 
153  /* Build up numa of specific data */
154  n = ptaGetCount(ptas);
155  if ((na = numaCreate(n)) == NULL)
156  return ERROR_INT("na not made", procName, 1);
157  for (i = 0; i < n; i++) {
158  ptaGetPt(ptas, i, &x, &y);
159  if (sorttype == L_SORT_BY_X)
160  numaAddNumber(na, x);
161  else
162  numaAddNumber(na, y);
163  }
164 
165  /* Get the sort index for data array */
166  *pnaindex = numaGetSortIndex(na, sortorder);
167  numaDestroy(&na);
168  if (!*pnaindex)
169  return ERROR_INT("naindex not made", procName, 1);
170  return 0;
171 }
172 
173 
181 PTA *
183  NUMA *naindex)
184 {
185 l_int32 i, index, n;
186 l_float32 x, y;
187 PTA *ptad;
188 
189  PROCNAME("ptaSortByIndex");
190 
191  if (!ptas)
192  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
193  if (!naindex)
194  return (PTA *)ERROR_PTR("naindex not defined", procName, NULL);
195 
196  /* Build up sorted pta using sort index */
197  n = numaGetCount(naindex);
198  if ((ptad = ptaCreate(n)) == NULL)
199  return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
200  for (i = 0; i < n; i++) {
201  numaGetIValue(naindex, i, &index);
202  ptaGetPt(ptas, index, &x, &y);
203  ptaAddPt(ptad, x, y);
204  }
205 
206  return ptad;
207 }
208 
209 
217 PTAA *
219  NUMA *naindex)
220 {
221 l_int32 i, n, index;
222 PTA *pta;
223 PTAA *ptaad;
224 
225  PROCNAME("ptaaSortByIndex");
226 
227  if (!ptaas)
228  return (PTAA *)ERROR_PTR("ptaas not defined", procName, NULL);
229  if (!naindex)
230  return (PTAA *)ERROR_PTR("naindex not defined", procName, NULL);
231 
232  n = ptaaGetCount(ptaas);
233  if (numaGetCount(naindex) != n)
234  return (PTAA *)ERROR_PTR("numa and ptaa sizes differ", procName, NULL);
235  ptaad = ptaaCreate(n);
236  for (i = 0; i < n; i++) {
237  numaGetIValue(naindex, i, &index);
238  pta = ptaaGetPta(ptaas, index, L_COPY);
239  ptaaAddPta(ptaad, pta, L_INSERT);
240  }
241 
242  return ptaad;
243 }
244 
245 
256 l_int32
258  l_float32 fract,
259  PTA *ptasort,
260  l_int32 sorttype,
261  l_float32 *pval)
262 {
263 l_int32 index, n;
264 PTA *ptas;
265 
266  PROCNAME("ptaGetRankValue");
267 
268  if (!pval)
269  return ERROR_INT("&val not defined", procName, 1);
270  *pval = 0.0;
271  if (!pta)
272  return ERROR_INT("pta not defined", procName, 1);
273  if (sorttype != L_SORT_BY_X && sorttype != L_SORT_BY_Y)
274  return ERROR_INT("invalid sort type", procName, 1);
275  if (fract < 0.0 || fract > 1.0)
276  return ERROR_INT("fract not in [0.0 ... 1.0]", procName, 1);
277  if ((n = ptaGetCount(pta)) == 0)
278  return ERROR_INT("pta empty", procName, 1);
279 
280  if (ptasort)
281  ptas = ptasort;
282  else
283  ptas = ptaSort(pta, sorttype, L_SORT_INCREASING, NULL);
284 
285  index = (l_int32)(fract * (l_float32)(n - 1) + 0.5);
286  if (sorttype == L_SORT_BY_X)
287  ptaGetPt(ptas, index, pval, NULL);
288  else /* sort by y */
289  ptaGetPt(ptas, index, NULL, pval);
290 
291  if (!ptasort) ptaDestroy(&ptas);
292  return 0;
293 }
294 
295 
296 /*---------------------------------------------------------------------*
297  * Set operations using aset (rbtree) *
298  *---------------------------------------------------------------------*/
316 PTA *
318  PTA *pta2)
319 {
320 PTA *pta3, *ptad;
321 
322  PROCNAME("ptaUnionByAset");
323 
324  if (!pta1)
325  return (PTA *)ERROR_PTR("pta1 not defined", procName, NULL);
326  if (!pta2)
327  return (PTA *)ERROR_PTR("pta2 not defined", procName, NULL);
328 
329  /* Join */
330  pta3 = ptaCopy(pta1);
331  ptaJoin(pta3, pta2, 0, -1);
332 
333  /* Eliminate duplicates */
334  ptad = ptaRemoveDupsByAset(pta3);
335  ptaDestroy(&pta3);
336  return ptad;
337 }
338 
339 
353 PTA *
355 {
356 l_int32 i, n, x, y;
357 PTA *ptad;
358 l_uint64 hash;
359 L_ASET *set;
360 RB_TYPE key;
361 
362  PROCNAME("ptaRemoveDupsByAset");
363 
364  if (!ptas)
365  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
366 
367  set = l_asetCreate(L_UINT_TYPE);
368  n = ptaGetCount(ptas);
369  ptad = ptaCreate(n);
370  for (i = 0; i < n; i++) {
371  ptaGetIPt(ptas, i, &x, &y);
372  l_hashPtToUint64(x, y, &hash);
373  key.utype = hash;
374  if (!l_asetFind(set, key)) {
375  ptaAddPt(ptad, x, y);
376  l_asetInsert(set, key);
377  }
378  }
379 
380  l_asetDestroy(&set);
381  return ptad;
382 }
383 
384 
400 PTA *
402  PTA *pta2)
403 {
404 l_int32 n1, n2, i, n, x, y;
405 l_uint64 hash;
406 L_ASET *set1, *set2;
407 RB_TYPE key;
408 PTA *pta_small, *pta_big, *ptad;
409 
410  PROCNAME("ptaIntersectionByAset");
411 
412  if (!pta1)
413  return (PTA *)ERROR_PTR("pta1 not defined", procName, NULL);
414  if (!pta2)
415  return (PTA *)ERROR_PTR("pta2 not defined", procName, NULL);
416 
417  /* Put the elements of the biggest array into a set */
418  n1 = ptaGetCount(pta1);
419  n2 = ptaGetCount(pta2);
420  pta_small = (n1 < n2) ? pta1 : pta2; /* do not destroy pta_small */
421  pta_big = (n1 < n2) ? pta2 : pta1; /* do not destroy pta_big */
422  set1 = l_asetCreateFromPta(pta_big);
423 
424  /* Build up the intersection of points */
425  ptad = ptaCreate(0);
426  n = ptaGetCount(pta_small);
427  set2 = l_asetCreate(L_UINT_TYPE);
428  for (i = 0; i < n; i++) {
429  ptaGetIPt(pta_small, i, &x, &y);
430  l_hashPtToUint64(x, y, &hash);
431  key.utype = hash;
432  if (l_asetFind(set1, key) && !l_asetFind(set2, key)) {
433  ptaAddPt(ptad, x, y);
434  l_asetInsert(set2, key);
435  }
436  }
437 
438  l_asetDestroy(&set1);
439  l_asetDestroy(&set2);
440  return ptad;
441 }
442 
443 
450 L_ASET *
452 {
453 l_int32 i, n, x, y;
454 l_uint64 hash;
455 L_ASET *set;
456 RB_TYPE key;
457 
458  PROCNAME("l_asetCreateFromPta");
459 
460  if (!pta)
461  return (L_ASET *)ERROR_PTR("pta not defined", procName, NULL);
462 
463  set = l_asetCreate(L_UINT_TYPE);
464  n = ptaGetCount(pta);
465  for (i = 0; i < n; i++) {
466  ptaGetIPt(pta, i, &x, &y);
467  l_hashPtToUint64(x, y, &hash);
468  key.utype = hash;
469  l_asetInsert(set, key);
470  }
471 
472  return set;
473 }
474 
475 
476 /*---------------------------------------------------------------------*
477  * Set operations using hashing (rbtree) *
478  *---------------------------------------------------------------------*/
492 PTA *
494  PTA *pta2)
495 {
496 PTA *pta3, *ptad;
497 
498  PROCNAME("ptaUnionByHash");
499 
500  if (!pta1)
501  return (PTA *)ERROR_PTR("pta1 not defined", procName, NULL);
502  if (!pta2)
503  return (PTA *)ERROR_PTR("pta2 not defined", procName, NULL);
504 
505  /* Join */
506  pta3 = ptaCopy(pta1);
507  ptaJoin(pta3, pta2, 0, -1);
508 
509  /* Eliminate duplicates */
510  ptaRemoveDupsByHash(pta3, &ptad, NULL);
511  ptaDestroy(&pta3);
512  return ptad;
513 }
514 
515 
542 l_int32
544  PTA **pptad,
545  L_DNAHASH **pdahash)
546 {
547 l_int32 i, n, index, items, x, y;
548 l_uint32 nsize;
549 l_uint64 key;
550 PTA *ptad;
551 L_DNAHASH *dahash;
552 
553  PROCNAME("ptaRemoveDupsByHash");
554 
555  if (pdahash) *pdahash = NULL;
556  if (!pptad)
557  return ERROR_INT("&ptad not defined", procName, 1);
558  *pptad = NULL;
559  if (!ptas)
560  return ERROR_INT("ptas not defined", procName, 1);
561 
562  n = ptaGetCount(ptas);
563  findNextLargerPrime(n / 20, &nsize); /* buckets in hash table */
564  dahash = l_dnaHashCreate(nsize, 8);
565  ptad = ptaCreate(n);
566  *pptad = ptad;
567  for (i = 0, items = 0; i < n; i++) {
568  ptaGetIPt(ptas, i, &x, &y);
569  ptaFindPtByHash(ptad, dahash, x, y, &index);
570  if (index < 0) { /* not found */
571  l_hashPtToUint64(x, y, &key);
572  l_dnaHashAdd(dahash, key, (l_float64)items);
573  ptaAddPt(ptad, x, y);
574  items++;
575  }
576  }
577 
578  if (pdahash)
579  *pdahash = dahash;
580  else
581  l_dnaHashDestroy(&dahash);
582  return 0;
583 }
584 
585 
599 PTA *
601  PTA *pta2)
602 {
603 l_int32 n1, n2, nsmall, i, x, y, index1, index2;
604 l_uint32 nsize2;
605 l_uint64 key;
606 L_DNAHASH *dahash1, *dahash2;
607 PTA *pta_small, *pta_big, *ptad;
608 
609  PROCNAME("ptaIntersectionByHash");
610 
611  if (!pta1)
612  return (PTA *)ERROR_PTR("pta1 not defined", procName, NULL);
613  if (!pta2)
614  return (PTA *)ERROR_PTR("pta2 not defined", procName, NULL);
615 
616  /* Put the elements of the biggest pta into a dnahash */
617  n1 = ptaGetCount(pta1);
618  n2 = ptaGetCount(pta2);
619  pta_small = (n1 < n2) ? pta1 : pta2; /* do not destroy pta_small */
620  pta_big = (n1 < n2) ? pta2 : pta1; /* do not destroy pta_big */
621  dahash1 = l_dnaHashCreateFromPta(pta_big);
622 
623  /* Build up the intersection of points. Add to ptad
624  * if the point is in pta_big (using dahash1) but hasn't
625  * yet been seen in the traversal of pta_small (using dahash2). */
626  ptad = ptaCreate(0);
627  nsmall = ptaGetCount(pta_small);
628  findNextLargerPrime(nsmall / 20, &nsize2); /* buckets in hash table */
629  dahash2 = l_dnaHashCreate(nsize2, 0);
630  for (i = 0; i < nsmall; i++) {
631  ptaGetIPt(pta_small, i, &x, &y);
632  ptaFindPtByHash(pta_big, dahash1, x, y, &index1);
633  if (index1 >= 0) { /* found */
634  ptaFindPtByHash(pta_small, dahash2, x, y, &index2);
635  if (index2 == -1) { /* not found */
636  ptaAddPt(ptad, x, y);
637  l_hashPtToUint64(x, y, &key);
638  l_dnaHashAdd(dahash2, key, (l_float64)i);
639  }
640  }
641  }
642 
643  l_dnaHashDestroy(&dahash1);
644  l_dnaHashDestroy(&dahash2);
645  return ptad;
646 }
647 
648 
673 l_int32
675  L_DNAHASH *dahash,
676  l_int32 x,
677  l_int32 y,
678  l_int32 *pindex)
679 {
680 l_int32 i, nvals, index, xi, yi;
681 l_uint64 key;
682 L_DNA *da;
683 
684  PROCNAME("ptaFindPtByHash");
685 
686  if (!pindex)
687  return ERROR_INT("&index not defined", procName, 1);
688  *pindex = -1;
689  if (!pta)
690  return ERROR_INT("pta not defined", procName, 1);
691  if (!dahash)
692  return ERROR_INT("dahash not defined", procName, 1);
693 
694  l_hashPtToUint64(x, y, &key);
695  da = l_dnaHashGetDna(dahash, key, L_NOCOPY);
696  if (!da) return 0;
697 
698  /* Run through the da, looking for this point */
699  nvals = l_dnaGetCount(da);
700  for (i = 0; i < nvals; i++) {
701  l_dnaGetIValue(da, i, &index);
702  ptaGetIPt(pta, index, &xi, &yi);
703  if (x == xi && y == yi) {
704  *pindex = index;
705  return 0;
706  }
707  }
708 
709  return 0;
710 }
711 
712 
719 L_DNAHASH *
721 {
722 l_int32 i, n, x, y;
723 l_uint32 nsize;
724 l_uint64 key;
725 L_DNAHASH *dahash;
726 
727  PROCNAME("l_dnaHashCreateFromPta");
728 
729  if (!pta)
730  return (L_DNAHASH *)ERROR_PTR("pta not defined", procName, NULL);
731 
732  /* Build up dnaHash of indices, hashed by a key that is
733  * a large linear combination of x and y values designed to
734  * randomize the key. Having about 20 pts in each bucket is
735  * roughly optimal for speed for large sets. */
736  n = ptaGetCount(pta);
737  findNextLargerPrime(n / 20, &nsize); /* buckets in hash table */
738 /* fprintf(stderr, "Prime used: %d\n", nsize); */
739 
740  /* Add each point, using the hash as key and the index into
741  * %ptas as the value. Storing the index enables operations
742  * that check for duplicates. */
743  dahash = l_dnaHashCreate(nsize, 8);
744  for (i = 0; i < n; i++) {
745  ptaGetIPt(pta, i, &x, &y);
746  l_hashPtToUint64(x, y, &key);
747  l_dnaHashAdd(dahash, key, (l_float64)i);
748  }
749 
750  return dahash;
751 }
l_int32 ptaaAddPta(PTAA *ptaa, PTA *pta, l_int32 copyflag)
ptaaAddPta()
Definition: ptabasic.c:970
L_DNA * l_dnaHashGetDna(L_DNAHASH *dahash, l_uint64 key, l_int32 copyflag)
l_dnaHashGetDna()
Definition: dnahash.c:232
l_int32 numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:472
NUMA * numaGetSortIndex(NUMA *na, l_int32 sortorder)
numaGetSortIndex()
Definition: numafunc1.c:2621
l_int32 l_dnaGetCount(L_DNA *da)
l_dnaGetCount()
Definition: dnabasic.c:597
l_int32 ptaFindPtByHash(PTA *pta, L_DNAHASH *dahash, l_int32 x, l_int32 y, l_int32 *pindex)
ptaFindPtByHash()
Definition: ptafunc2.c:674
l_int32 ptaAddPt(PTA *pta, l_float32 x, l_float32 y)
ptaAddPt()
Definition: ptabasic.c:341
l_int32 ptaRemoveDupsByHash(PTA *ptas, PTA **pptad, L_DNAHASH **pdahash)
ptaRemoveDupsByHash()
Definition: ptafunc2.c:543
l_int32 ptaGetPt(PTA *pta, l_int32 index, l_float32 *px, l_float32 *py)
ptaGetPt()
Definition: ptabasic.c:524
Definition: pix.h:704
void l_dnaHashDestroy(L_DNAHASH **pdahash)
l_dnaHashDestroy()
Definition: dnahash.c:152
PTA * ptaCreate(l_int32 n)
ptaCreate()
Definition: ptabasic.c:115
Definition: array.h:83
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:186
l_int32 ptaGetCount(PTA *pta)
ptaGetCount()
Definition: ptabasic.c:503
PTA * ptaSort(PTA *ptas, l_int32 sorttype, l_int32 sortorder, NUMA **pnaindex)
ptaSort()
Definition: ptafunc2.c:89
PTA * ptaRemoveDupsByAset(PTA *ptas)
ptaRemoveDupsByAset()
Definition: ptafunc2.c:354
l_int32 ptaGetSortIndex(PTA *ptas, l_int32 sorttype, l_int32 sortorder, NUMA **pnaindex)
ptaGetSortIndex()
Definition: ptafunc2.c:132
l_int32 l_hashPtToUint64(l_int32 x, l_int32 y, l_uint64 *phash)
l_hashPtToUint64()
Definition: utils1.c:615
l_int32 l_dnaGetIValue(L_DNA *da, l_int32 index, l_int32 *pival)
l_dnaGetIValue()
Definition: dnabasic.c:693
PTAA * ptaaSortByIndex(PTAA *ptaas, NUMA *naindex)
ptaaSortByIndex()
Definition: ptafunc2.c:218
l_int32 findNextLargerPrime(l_int32 start, l_uint32 *pprime)
findNextLargerPrime()
Definition: utils1.c:679
PTA * ptaaGetPta(PTAA *ptaa, l_int32 index, l_int32 accessflag)
ptaaGetPta()
Definition: ptabasic.c:1060
Definition: array.h:59
static const l_int32 L_INSERT
Definition: pix.h:710
l_int32 ptaJoin(PTA *ptad, PTA *ptas, l_int32 istart, l_int32 iend)
ptaJoin()
Definition: ptafunc1.c:154
l_int32 numaGetCount(NUMA *na)
numaGetCount()
Definition: numabasic.c:630
Definition: pix.h:532
PTA * ptaUnionByAset(PTA *pta1, PTA *pta2)
ptaUnionByAset()
Definition: ptafunc2.c:317
l_int32 l_dnaHashAdd(L_DNAHASH *dahash, l_uint64 key, l_float64 value)
l_dnaHashAdd()
Definition: dnahash.c:267
l_int32 ptaGetRankValue(PTA *pta, l_float32 fract, PTA *ptasort, l_int32 sorttype, l_float32 *pval)
ptaGetRankValue()
Definition: ptafunc2.c:257
PTA * ptaCopy(PTA *pta)
ptaCopy()
Definition: ptabasic.c:224
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:359
PTA * ptaIntersectionByHash(PTA *pta1, PTA *pta2)
ptaIntersectionByHash()
Definition: ptafunc2.c:600
PTA * ptaIntersectionByAset(PTA *pta1, PTA *pta2)
ptaIntersectionByAset()
Definition: ptafunc2.c:401
L_ASET * l_asetCreateFromPta(PTA *pta)
l_asetCreateFromPta()
Definition: ptafunc2.c:451
l_int32 ptaGetIPt(PTA *pta, l_int32 index, l_int32 *px, l_int32 *py)
ptaGetIPt()
Definition: ptabasic.c:554
l_int32 ptaaGetCount(PTAA *ptaa)
ptaaGetCount()
Definition: ptabasic.c:1040
Definition: pix.h:705
void ptaDestroy(PTA **ppta)
ptaDestroy()
Definition: ptabasic.c:191
L_DNAHASH * l_dnaHashCreateFromPta(PTA *pta)
l_dnaHashCreateFromPta()
Definition: ptafunc2.c:720
l_int32 numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition: numabasic.c:726
Definition: rbtree.h:61
L_DNAHASH * l_dnaHashCreate(l_int32 nbuckets, l_int32 initsize)
l_dnaHashCreate()
Definition: dnahash.c:122
PTAA * ptaaCreate(l_int32 n)
ptaaCreate()
Definition: ptabasic.c:905
PTA * ptaSortByIndex(PTA *ptas, NUMA *naindex)
ptaSortByIndex()
Definition: ptafunc2.c:182
PTA * ptaUnionByHash(PTA *pta1, PTA *pta2)
ptaUnionByHash()
Definition: ptafunc2.c:493
Definition: pix.h:517