Leptonica  1.82.0
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 
77 #ifdef HAVE_CONFIG_H
78 #include <config_auto.h>
79 #endif /* HAVE_CONFIG_H */
80 
81 #include "allheaders.h"
82 
83 /*---------------------------------------------------------------------*
84  * Sorting *
85  *---------------------------------------------------------------------*/
96 PTA *
97 ptaSort(PTA *ptas,
98  l_int32 sorttype,
99  l_int32 sortorder,
100  NUMA **pnaindex)
101 {
102 PTA *ptad;
103 NUMA *naindex;
104 
105  PROCNAME("ptaSort");
106 
107  if (pnaindex) *pnaindex = NULL;
108  if (!ptas)
109  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
110  if (sorttype != L_SORT_BY_X && sorttype != L_SORT_BY_Y)
111  return (PTA *)ERROR_PTR("invalid sort type", procName, NULL);
112  if (sortorder != L_SORT_INCREASING && sortorder != L_SORT_DECREASING)
113  return (PTA *)ERROR_PTR("invalid sort order", procName, NULL);
114 
115  if (ptaGetSortIndex(ptas, sorttype, sortorder, &naindex) != 0)
116  return (PTA *)ERROR_PTR("naindex not made", procName, NULL);
117 
118  ptad = ptaSortByIndex(ptas, naindex);
119  if (pnaindex)
120  *pnaindex = naindex;
121  else
122  numaDestroy(&naindex);
123  if (!ptad)
124  return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
125  return ptad;
126 }
127 
128 
138 l_ok
140  l_int32 sorttype,
141  l_int32 sortorder,
142  NUMA **pnaindex)
143 {
144 l_int32 i, n;
145 l_float32 x, y;
146 NUMA *na, *nai;
147 
148  PROCNAME("ptaGetSortIndex");
149 
150  if (!pnaindex)
151  return ERROR_INT("&naindex not defined", procName, 1);
152  *pnaindex = NULL;
153  if (!ptas)
154  return ERROR_INT("ptas not defined", procName, 1);
155  if (sorttype != L_SORT_BY_X && sorttype != L_SORT_BY_Y)
156  return ERROR_INT("invalid sort type", procName, 1);
157  if (sortorder != L_SORT_INCREASING && sortorder != L_SORT_DECREASING)
158  return ERROR_INT("invalid sort order", procName, 1);
159 
160  /* Build up numa of specific data */
161  n = ptaGetCount(ptas);
162  if ((na = numaCreate(n)) == NULL)
163  return ERROR_INT("na not made", procName, 1);
164  for (i = 0; i < n; i++) {
165  ptaGetPt(ptas, i, &x, &y);
166  if (sorttype == L_SORT_BY_X)
167  numaAddNumber(na, x);
168  else
169  numaAddNumber(na, y);
170  }
171 
172  /* Get the sort index for data array */
173  nai = numaGetSortIndex(na, sortorder);
174  numaDestroy(&na);
175  if (!nai)
176  return ERROR_INT("naindex not made", procName, 1);
177  *pnaindex = nai;
178  return 0;
179 }
180 
181 
189 PTA *
191  NUMA *naindex)
192 {
193 l_int32 i, index, n;
194 l_float32 x, y;
195 PTA *ptad;
196 
197  PROCNAME("ptaSortByIndex");
198 
199  if (!ptas)
200  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
201  if (!naindex)
202  return (PTA *)ERROR_PTR("naindex not defined", procName, NULL);
203 
204  /* Build up sorted pta using sort index */
205  n = numaGetCount(naindex);
206  if ((ptad = ptaCreate(n)) == NULL)
207  return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
208  for (i = 0; i < n; i++) {
209  numaGetIValue(naindex, i, &index);
210  ptaGetPt(ptas, index, &x, &y);
211  ptaAddPt(ptad, x, y);
212  }
213 
214  return ptad;
215 }
216 
217 
225 PTAA *
227  NUMA *naindex)
228 {
229 l_int32 i, n, index;
230 PTA *pta;
231 PTAA *ptaad;
232 
233  PROCNAME("ptaaSortByIndex");
234 
235  if (!ptaas)
236  return (PTAA *)ERROR_PTR("ptaas not defined", procName, NULL);
237  if (!naindex)
238  return (PTAA *)ERROR_PTR("naindex not defined", procName, NULL);
239 
240  n = ptaaGetCount(ptaas);
241  if (numaGetCount(naindex) != n)
242  return (PTAA *)ERROR_PTR("numa and ptaa sizes differ", procName, NULL);
243  ptaad = ptaaCreate(n);
244  for (i = 0; i < n; i++) {
245  numaGetIValue(naindex, i, &index);
246  pta = ptaaGetPta(ptaas, index, L_COPY);
247  ptaaAddPta(ptaad, pta, L_INSERT);
248  }
249 
250  return ptaad;
251 }
252 
253 
264 l_ok
266  l_float32 fract,
267  PTA *ptasort,
268  l_int32 sorttype,
269  l_float32 *pval)
270 {
271 l_int32 index, n;
272 PTA *ptas;
273 
274  PROCNAME("ptaGetRankValue");
275 
276  if (!pval)
277  return ERROR_INT("&val not defined", procName, 1);
278  *pval = 0.0;
279  if (!pta)
280  return ERROR_INT("pta not defined", procName, 1);
281  if (sorttype != L_SORT_BY_X && sorttype != L_SORT_BY_Y)
282  return ERROR_INT("invalid sort type", procName, 1);
283  if (fract < 0.0 || fract > 1.0)
284  return ERROR_INT("fract not in [0.0 ... 1.0]", procName, 1);
285  if ((n = ptaGetCount(pta)) == 0)
286  return ERROR_INT("pta empty", procName, 1);
287 
288  if (ptasort)
289  ptas = ptasort;
290  else
291  ptas = ptaSort(pta, sorttype, L_SORT_INCREASING, NULL);
292 
293  index = (l_int32)(fract * (l_float32)(n - 1) + 0.5);
294  if (sorttype == L_SORT_BY_X)
295  ptaGetPt(ptas, index, pval, NULL);
296  else /* sort by y */
297  ptaGetPt(ptas, index, NULL, pval);
298 
299  if (!ptasort) ptaDestroy(&ptas);
300  return 0;
301 }
302 
303 
316 PTA *
318 {
319 l_int32 index, i, j, n, nx, ny, start, end;
320 l_float32 x, y, yp, val;
321 NUMA *na1, *na2, *nas, *nax;
322 PTA *pta1, *ptad;
323 
324  PROCNAME("ptaSort2d");
325 
326  if (!pta)
327  return (PTA *)ERROR_PTR("pta not defined", procName, NULL);
328 
329  /* Sort by row-major (y first, then x). After sort by y,
330  * the x values at the same y are not sorted. */
331  pta1 = ptaSort(pta, L_SORT_BY_Y, L_SORT_INCREASING, NULL);
332 
333  /* Find start and ending indices with the same y value */
334  n = ptaGetCount(pta1);
335  na1 = numaCreate(0); /* holds start index of sequence with same y */
336  na2 = numaCreate(0); /* holds end index of sequence with same y */
337  numaAddNumber(na1, 0);
338  ptaGetPt(pta1, 0, &x, &yp);
339  for (i = 1; i < n; i++) {
340  ptaGetPt(pta1, i, &x, &y);
341  if (y != yp) {
342  numaAddNumber(na1, i);
343  numaAddNumber(na2, i - 1);
344  }
345  yp = y;
346  }
347  numaAddNumber(na2, n - 1);
348 
349  /* Sort by increasing x each set with the same y value */
350  ptad = ptaCreate(n);
351  ny = numaGetCount(na1); /* number of distinct y values */
352  for (i = 0, index = 0; i < ny; i++) {
353  numaGetIValue(na1, i, &start);
354  numaGetIValue(na2, i, &end);
355  nx = end - start + 1; /* number of points with current y value */
356  if (nx == 1) {
357  ptaGetPt(pta1, index++, &x, &y);
358  ptaAddPt(ptad, x, y);
359  } else {
360  /* More than 1 point; extract and sort the x values */
361  nax = numaCreate(nx);
362  for (j = 0; j < nx; j++) {
363  ptaGetPt(pta1, index + j, &x, &y);
364  numaAddNumber(nax, x);
365  }
366  nas = numaSort(NULL, nax, L_SORT_INCREASING);
367  /* Add the points with x sorted */
368  for (j = 0; j < nx; j++) {
369  numaGetFValue(nas, j, &val);
370  ptaAddPt(ptad, val, y);
371  }
372  index += nx;
373  numaDestroy(&nax);
374  numaDestroy(&nas);
375  }
376  }
377  numaDestroy(&na1);
378  numaDestroy(&na2);
379  ptaDestroy(&pta1);
380  return ptad;
381 }
382 
383 
398 l_ok
399 ptaEqual(PTA *pta1,
400  PTA *pta2,
401  l_int32 *psame)
402 {
403 l_int32 i, n1, n2;
404 l_float32 x1, y1, x2, y2;
405 PTA *ptas1, *ptas2;
406 
407  PROCNAME("ptaEqual");
408 
409  if (!psame)
410  return ERROR_INT("&same not defined", procName, 1);
411  *psame = 0.0;
412  if (!pta1 || !pta2)
413  return ERROR_INT("pta1 and pta2 not both defined", procName, 1);
414 
415  n1 = ptaGetCount(pta1);
416  n2 = ptaGetCount(pta2);
417  if (n1 != n2) return 0;
418 
419  /* 2d sort each and compare */
420  ptas1 = ptaSort2d(pta1);
421  ptas2 = ptaSort2d(pta2);
422  for (i = 0; i < n1; i++) {
423  ptaGetPt(ptas1, i, &x1, &y1);
424  ptaGetPt(ptas2, i, &x2, &y2);
425  if (x1 != x2 || y1 != y2) {
426  ptaDestroy(&ptas1);
427  ptaDestroy(&ptas2);
428  return 0;
429  }
430  }
431 
432  *psame = 1;
433  ptaDestroy(&ptas1);
434  ptaDestroy(&ptas2);
435  return 0;
436 }
437 
438 
439 /*---------------------------------------------------------------------*
440  * Set operations using aset (rbtree) *
441  *---------------------------------------------------------------------*/
448 L_ASET *
450 {
451 l_int32 i, n, x, y;
452 l_uint64 hash;
453 L_ASET *set;
454 RB_TYPE key;
455 
456  PROCNAME("l_asetCreateFromPta");
457 
458  if (!pta)
459  return (L_ASET *)ERROR_PTR("pta not defined", procName, NULL);
460 
461  set = l_asetCreate(L_UINT_TYPE);
462  n = ptaGetCount(pta);
463  for (i = 0; i < n; i++) {
464  ptaGetIPt(pta, i, &x, &y);
465  l_hashPtToUint64(x, y, &hash);
466  key.utype = hash;
467  l_asetInsert(set, key);
468  }
469 
470  return set;
471 }
472 
473 
488 l_ok
490  PTA **pptad)
491 {
492 l_int32 i, n, x, y;
493 PTA *ptad;
494 l_uint64 hash;
495 L_ASET *set;
496 RB_TYPE key;
497 
498  PROCNAME("ptaRemoveDupsByAset");
499 
500  if (!pptad)
501  return ERROR_INT("&ptad not defined", procName, 1);
502  *pptad = NULL;
503  if (!ptas)
504  return ERROR_INT("ptas not defined", procName, 1);
505 
506  set = l_asetCreate(L_UINT_TYPE);
507  n = ptaGetCount(ptas);
508  ptad = ptaCreate(n);
509  *pptad = ptad;
510  for (i = 0; i < n; i++) {
511  ptaGetIPt(ptas, i, &x, &y);
512  l_hashPtToUint64(x, y, &hash);
513  key.utype = hash;
514  if (!l_asetFind(set, key)) {
515  ptaAddPt(ptad, x, y);
516  l_asetInsert(set, key);
517  }
518  }
519 
520  l_asetDestroy(&set);
521  return 0;
522 }
523 
524 
544 l_ok
546  PTA *pta2,
547  PTA **pptad)
548 {
549 PTA *pta3;
550 
551  PROCNAME("ptaUnionByAset");
552 
553  if (!pptad)
554  return ERROR_INT("&ptad not defined", procName, 1);
555  *pptad = NULL;
556  if (!pta1)
557  return ERROR_INT("pta1 not defined", procName, 1);
558  if (!pta2)
559  return ERROR_INT("pta2 not defined", procName, 1);
560 
561  /* Join */
562  pta3 = ptaCopy(pta1);
563  ptaJoin(pta3, pta2, 0, -1);
564 
565  /* Eliminate duplicates */
566  ptaRemoveDupsByAset(pta3, pptad);
567  ptaDestroy(&pta3);
568  return 0;
569 }
570 
571 
589 l_ok
591  PTA *pta2,
592  PTA **pptad)
593 {
594 l_int32 n1, n2, i, n, x, y;
595 l_uint64 hash;
596 L_ASET *set1, *set2;
597 RB_TYPE key;
598 PTA *pta_small, *pta_big, *ptad;
599 
600  PROCNAME("ptaIntersectionByAset");
601 
602  if (!pptad)
603  return ERROR_INT("&ptad not defined", procName, 1);
604  *pptad = NULL;
605  if (!pta1)
606  return ERROR_INT("pta1 not defined", procName, 1);
607  if (!pta2)
608  return ERROR_INT("pta2 not defined", procName, 1);
609 
610  /* Put the elements of the biggest array into a set */
611  n1 = ptaGetCount(pta1);
612  n2 = ptaGetCount(pta2);
613  pta_small = (n1 < n2) ? pta1 : pta2; /* do not destroy pta_small */
614  pta_big = (n1 < n2) ? pta2 : pta1; /* do not destroy pta_big */
615  set1 = l_asetCreateFromPta(pta_big);
616 
617  /* Build up the intersection of points */
618  ptad = ptaCreate(0);
619  *pptad = ptad;
620  n = ptaGetCount(pta_small);
621  set2 = l_asetCreate(L_UINT_TYPE);
622  for (i = 0; i < n; i++) {
623  ptaGetIPt(pta_small, i, &x, &y);
624  l_hashPtToUint64(x, y, &hash);
625  key.utype = hash;
626  if (l_asetFind(set1, key) && !l_asetFind(set2, key)) {
627  ptaAddPt(ptad, x, y);
628  l_asetInsert(set2, key);
629  }
630  }
631 
632  l_asetDestroy(&set1);
633  l_asetDestroy(&set2);
634  return 0;
635 }
636 
637 
638 /*--------------------------------------------------------------------------*
639  * Hashmap operations *
640  *--------------------------------------------------------------------------*/
653 L_HASHMAP *
655 {
656 l_int32 i, n, x, y;
657 l_uint64 key;
658 L_HASHITEM *hitem;
659 L_HASHMAP *hmap;
660 
661  PROCNAME("l_hmapCreateFromPta");
662 
663  if (!pta)
664  return (L_HASHMAP *)ERROR_PTR("pta not defined", procName, NULL);
665 
666  n = ptaGetCount(pta);
667  if ((hmap = l_hmapCreate(0.51 * n, 2)) == NULL)
668  return (L_HASHMAP *)ERROR_PTR("hmap not made", procName, NULL);
669  for (i = 0; i < n; i++) {
670  ptaGetIPt(pta, i, &x, &y);
671  l_hashPtToUint64(x, y, &key);
672  hitem = l_hmapLookup(hmap, key, i, L_HMAP_CREATE);
673  }
674  return hmap;
675 }
676 
677 
691 l_ok
693  PTA **pptad,
694  L_HASHMAP **phmap)
695 {
696 l_int32 i, x, y, tabsize;
697 l_uint64 key;
698 PTA *ptad;
699 L_HASHITEM *hitem;
700 L_HASHMAP *hmap;
701 
702  PROCNAME("ptaRemoveDupsByHmap");
703 
704  if (phmap) *phmap = NULL;
705  if (!pptad)
706  return ERROR_INT("&ptad not defined", procName, 1);
707  *pptad = NULL;
708  if (!ptas)
709  return ERROR_INT("ptas not defined", procName, 1);
710 
711  /* Traverse the hashtable lists */
712  if ((hmap = l_hmapCreateFromPta(ptas)) == NULL)
713  return ERROR_INT("hmap not made", procName, 1);
714  ptad = ptaCreate(0);
715  *pptad = ptad;
716  tabsize = hmap->tabsize;
717  for (i = 0; i < tabsize; i++) {
718  hitem = hmap->hashtab[i];
719  while (hitem) {
720  ptaGetIPt(ptas, hitem->val, &x, &y);
721  ptaAddPt(ptad, x, y);
722  hitem = hitem->next;
723  }
724  }
725 
726  if (phmap)
727  *phmap = hmap;
728  else
729  l_hmapDestroy(&hmap);
730  return 0;
731 }
732 
733 
747 l_ok
749  PTA *pta2,
750  PTA **pptad)
751 {
752 PTA *pta3;
753 
754  PROCNAME("ptaUnionByHmap");
755 
756  if (!pptad)
757  return ERROR_INT("&ptad not defined", procName, 1);
758  *pptad = NULL;
759  if (!pta1)
760  return ERROR_INT("pta1 not defined", procName, 1);
761  if (!pta2)
762  return ERROR_INT("pta2 not defined", procName, 1);
763 
764  pta3 = ptaCopy(pta1);
765  if (ptaJoin(pta3, pta2, 0, -1) == 1) {
766  ptaDestroy(&pta3);
767  return ERROR_INT("pta join failed", procName, 1);
768  }
769  ptaRemoveDupsByHmap(pta3, pptad, NULL);
770  ptaDestroy(&pta3);
771  return 0;
772 }
773 
774 
788 l_ok
790  PTA *pta2,
791  PTA **pptad)
792 {
793 l_int32 i, n1, n2, n, x, y;
794 l_uint64 key;
795 PTA *pta_small, *pta_big, *ptad;
796 L_HASHITEM *hitem;
797 L_HASHMAP *hmap;
798 
799  PROCNAME("ptaIntersectionByHmap");
800 
801  if (!pptad)
802  return ERROR_INT("&ptad not defined", procName, 1);
803  *pptad = NULL;
804  if (!pta1)
805  return ERROR_INT("pta1 not defined", procName, 1);
806  if (!pta2)
807  return ERROR_INT("pta2 not defined", procName, 1);
808 
809  /* Make a hashmap for the elements of the biggest array */
810  n1 = ptaGetCount(pta1);
811  n2 = ptaGetCount(pta2);
812  pta_small = (n1 < n2) ? pta1 : pta2; /* do not destroy pta_small */
813  pta_big = (n1 < n2) ? pta2 : pta1; /* do not destroy pta_big */
814  if ((hmap = l_hmapCreateFromPta(pta_big)) == NULL)
815  return ERROR_INT("hmap not made", procName, 1);
816 
817  /* Go through the smallest array, doing a lookup of its (x,y) into
818  * the big array hashmap. If an hitem is returned, check the count.
819  * If the count is 0, ignore; otherwise, add the point to the
820  * output ptad and set the count in the hitem to 0, indicating
821  * that the point has already been added. */
822  ptad = ptaCreate(0);
823  *pptad = ptad;
824  n = ptaGetCount(pta_small);
825  for (i = 0; i < n; i++) {
826  ptaGetIPt(pta_small, i, &x, &y);
827  l_hashPtToUint64(x, y, &key);
828  hitem = l_hmapLookup(hmap, key, i, L_HMAP_CHECK);
829  if (!hitem || hitem->count == 0)
830  continue;
831  ptaAddPt(ptad, x, y);
832  hitem->count = 0;
833  }
834  l_hmapDestroy(&hmap);
835  return 0;
836 }
837 
838 
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:478
l_ok numaGetFValue(NUMA *na, l_int32 index, l_float32 *pval)
numaGetFValue()
Definition: numabasic.c:719
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:194
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:366
l_int32 numaGetCount(NUMA *na)
numaGetCount()
Definition: numabasic.c:658
l_ok numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition: numabasic.c:754
NUMA * numaSort(NUMA *naout, NUMA *nain, l_int32 sortorder)
numaSort()
Definition: numafunc1.c:2650
NUMA * numaGetSortIndex(NUMA *na, l_int32 sortorder)
numaGetSortIndex()
Definition: numafunc1.c:2751
@ L_SORT_BY_Y
Definition: pix.h:736
@ L_SORT_BY_X
Definition: pix.h:735
@ L_COPY
Definition: pix.h:712
@ L_INSERT
Definition: pix.h:711
@ L_SORT_DECREASING
Definition: pix.h:730
@ L_SORT_INCREASING
Definition: pix.h:729
PTAA * ptaaCreate(l_int32 n)
ptaaCreate()
Definition: ptabasic.c:976
PTA * ptaaGetPta(PTAA *ptaa, l_int32 index, l_int32 accessflag)
ptaaGetPta()
Definition: ptabasic.c:1145
l_ok ptaGetIPt(PTA *pta, l_int32 index, l_int32 *px, l_int32 *py)
ptaGetIPt()
Definition: ptabasic.c:578
l_ok ptaaAddPta(PTAA *ptaa, PTA *pta, l_int32 copyflag)
ptaaAddPta()
Definition: ptabasic.c:1038
l_int32 ptaaGetCount(PTAA *ptaa)
ptaaGetCount()
Definition: ptabasic.c:1125
l_ok ptaAddPt(PTA *pta, l_float32 x, l_float32 y)
ptaAddPt()
Definition: ptabasic.c:343
l_ok ptaGetPt(PTA *pta, l_int32 index, l_float32 *px, l_float32 *py)
ptaGetPt()
Definition: ptabasic.c:548
l_int32 ptaGetCount(PTA *pta)
ptaGetCount()
Definition: ptabasic.c:527
PTA * ptaCreate(l_int32 n)
ptaCreate()
Definition: ptabasic.c:120
void ptaDestroy(PTA **ppta)
ptaDestroy()
Definition: ptabasic.c:195
PTA * ptaCopy(PTA *pta)
ptaCopy()
Definition: ptabasic.c:226
l_ok ptaJoin(PTA *ptad, PTA *ptas, l_int32 istart, l_int32 iend)
ptaJoin()
Definition: ptafunc1.c:167
PTA * ptaSort(PTA *ptas, l_int32 sorttype, l_int32 sortorder, NUMA **pnaindex)
ptaSort()
Definition: ptafunc2.c:97
l_ok ptaUnionByHmap(PTA *pta1, PTA *pta2, PTA **pptad)
ptaUnionByHmap()
Definition: ptafunc2.c:748
PTA * ptaSort2d(PTA *pta)
ptaSort2d()
Definition: ptafunc2.c:317
L_ASET * l_asetCreateFromPta(PTA *pta)
l_asetCreateFromPta()
Definition: ptafunc2.c:449
l_ok ptaIntersectionByAset(PTA *pta1, PTA *pta2, PTA **pptad)
ptaIntersectionByAset()
Definition: ptafunc2.c:590
l_ok ptaUnionByAset(PTA *pta1, PTA *pta2, PTA **pptad)
ptaUnionByAset()
Definition: ptafunc2.c:545
PTAA * ptaaSortByIndex(PTAA *ptaas, NUMA *naindex)
ptaaSortByIndex()
Definition: ptafunc2.c:226
l_ok ptaEqual(PTA *pta1, PTA *pta2, l_int32 *psame)
ptaEqual()
Definition: ptafunc2.c:399
l_ok ptaGetRankValue(PTA *pta, l_float32 fract, PTA *ptasort, l_int32 sorttype, l_float32 *pval)
ptaGetRankValue()
Definition: ptafunc2.c:265
l_ok ptaRemoveDupsByAset(PTA *ptas, PTA **pptad)
ptaRemoveDupsByAset()
Definition: ptafunc2.c:489
l_ok ptaIntersectionByHmap(PTA *pta1, PTA *pta2, PTA **pptad)
ptaIntersectionByHmap()
Definition: ptafunc2.c:789
l_ok ptaRemoveDupsByHmap(PTA *ptas, PTA **pptad, L_HASHMAP **phmap)
ptaRemoveDupsByHmap()
Definition: ptafunc2.c:692
L_HASHMAP * l_hmapCreateFromPta(PTA *pta)
l_hmapCreateFromPta()
Definition: ptafunc2.c:654
l_ok ptaGetSortIndex(PTA *ptas, l_int32 sorttype, l_int32 sortorder, NUMA **pnaindex)
ptaGetSortIndex()
Definition: ptafunc2.c:139
PTA * ptaSortByIndex(PTA *ptas, NUMA *naindex)
ptaSortByIndex()
Definition: ptafunc2.c:190
l_uint64 val
Definition: hashmap.h:117
l_int32 count
Definition: hashmap.h:118
struct L_Hashitem * next
Definition: hashmap.h:119
struct L_Hashitem ** hashtab
Definition: hashmap.h:106
l_int32 tabsize
Definition: hashmap.h:107
Definition: array.h:71
Definition: pix.h:517
Definition: pix.h:531
Definition: rbtree.h:62
l_ok l_hashPtToUint64(l_int32 x, l_int32 y, l_uint64 *phash)
l_hashPtToUint64()
Definition: utils1.c:807