Leptonica  1.83.1
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  if (pnaindex) *pnaindex = NULL;
106  if (!ptas)
107  return (PTA *)ERROR_PTR("ptas not defined", __func__, NULL);
108  if (sorttype != L_SORT_BY_X && sorttype != L_SORT_BY_Y)
109  return (PTA *)ERROR_PTR("invalid sort type", __func__, NULL);
110  if (sortorder != L_SORT_INCREASING && sortorder != L_SORT_DECREASING)
111  return (PTA *)ERROR_PTR("invalid sort order", __func__, NULL);
112 
113  if (ptaGetSortIndex(ptas, sorttype, sortorder, &naindex) != 0)
114  return (PTA *)ERROR_PTR("naindex not made", __func__, NULL);
115 
116  ptad = ptaSortByIndex(ptas, naindex);
117  if (pnaindex)
118  *pnaindex = naindex;
119  else
120  numaDestroy(&naindex);
121  if (!ptad)
122  return (PTA *)ERROR_PTR("ptad not made", __func__, NULL);
123  return ptad;
124 }
125 
126 
136 l_ok
138  l_int32 sorttype,
139  l_int32 sortorder,
140  NUMA **pnaindex)
141 {
142 l_int32 i, n;
143 l_float32 x, y;
144 NUMA *na, *nai;
145 
146  if (!pnaindex)
147  return ERROR_INT("&naindex not defined", __func__, 1);
148  *pnaindex = NULL;
149  if (!ptas)
150  return ERROR_INT("ptas not defined", __func__, 1);
151  if (sorttype != L_SORT_BY_X && sorttype != L_SORT_BY_Y)
152  return ERROR_INT("invalid sort type", __func__, 1);
153  if (sortorder != L_SORT_INCREASING && sortorder != L_SORT_DECREASING)
154  return ERROR_INT("invalid sort order", __func__, 1);
155 
156  /* Build up numa of specific data */
157  n = ptaGetCount(ptas);
158  if ((na = numaCreate(n)) == NULL)
159  return ERROR_INT("na not made", __func__, 1);
160  for (i = 0; i < n; i++) {
161  ptaGetPt(ptas, i, &x, &y);
162  if (sorttype == L_SORT_BY_X)
163  numaAddNumber(na, x);
164  else
165  numaAddNumber(na, y);
166  }
167 
168  /* Get the sort index for data array */
169  nai = numaGetSortIndex(na, sortorder);
170  numaDestroy(&na);
171  if (!nai)
172  return ERROR_INT("naindex not made", __func__, 1);
173  *pnaindex = nai;
174  return 0;
175 }
176 
177 
185 PTA *
187  NUMA *naindex)
188 {
189 l_int32 i, index, n;
190 l_float32 x, y;
191 PTA *ptad;
192 
193  if (!ptas)
194  return (PTA *)ERROR_PTR("ptas not defined", __func__, NULL);
195  if (!naindex)
196  return (PTA *)ERROR_PTR("naindex not defined", __func__, NULL);
197 
198  /* Build up sorted pta using sort index */
199  n = numaGetCount(naindex);
200  if ((ptad = ptaCreate(n)) == NULL)
201  return (PTA *)ERROR_PTR("ptad not made", __func__, NULL);
202  for (i = 0; i < n; i++) {
203  numaGetIValue(naindex, i, &index);
204  ptaGetPt(ptas, index, &x, &y);
205  ptaAddPt(ptad, x, y);
206  }
207 
208  return ptad;
209 }
210 
211 
219 PTAA *
221  NUMA *naindex)
222 {
223 l_int32 i, n, index;
224 PTA *pta;
225 PTAA *ptaad;
226 
227  if (!ptaas)
228  return (PTAA *)ERROR_PTR("ptaas not defined", __func__, NULL);
229  if (!naindex)
230  return (PTAA *)ERROR_PTR("naindex not defined", __func__, NULL);
231 
232  n = ptaaGetCount(ptaas);
233  if (numaGetCount(naindex) != n)
234  return (PTAA *)ERROR_PTR("numa and ptaa sizes differ", __func__, 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_ok
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  if (!pval)
267  return ERROR_INT("&val not defined", __func__, 1);
268  *pval = 0.0;
269  if (!pta)
270  return ERROR_INT("pta not defined", __func__, 1);
271  if (sorttype != L_SORT_BY_X && sorttype != L_SORT_BY_Y)
272  return ERROR_INT("invalid sort type", __func__, 1);
273  if (fract < 0.0 || fract > 1.0)
274  return ERROR_INT("fract not in [0.0 ... 1.0]", __func__, 1);
275  if ((n = ptaGetCount(pta)) == 0)
276  return ERROR_INT("pta empty", __func__, 1);
277 
278  if (ptasort)
279  ptas = ptasort;
280  else
281  ptas = ptaSort(pta, sorttype, L_SORT_INCREASING, NULL);
282 
283  index = (l_int32)(fract * (l_float32)(n - 1) + 0.5);
284  if (sorttype == L_SORT_BY_X)
285  ptaGetPt(ptas, index, pval, NULL);
286  else /* sort by y */
287  ptaGetPt(ptas, index, NULL, pval);
288 
289  if (!ptasort) ptaDestroy(&ptas);
290  return 0;
291 }
292 
293 
306 PTA *
308 {
309 l_int32 index, i, j, n, nx, ny, start, end;
310 l_float32 x, y, yp, val;
311 NUMA *na1, *na2, *nas, *nax;
312 PTA *pta1, *ptad;
313 
314  if (!pta)
315  return (PTA *)ERROR_PTR("pta not defined", __func__, NULL);
316 
317  /* Sort by row-major (y first, then x). After sort by y,
318  * the x values at the same y are not sorted. */
319  pta1 = ptaSort(pta, L_SORT_BY_Y, L_SORT_INCREASING, NULL);
320 
321  /* Find start and ending indices with the same y value */
322  n = ptaGetCount(pta1);
323  na1 = numaCreate(0); /* holds start index of sequence with same y */
324  na2 = numaCreate(0); /* holds end index of sequence with same y */
325  numaAddNumber(na1, 0);
326  ptaGetPt(pta1, 0, &x, &yp);
327  for (i = 1; i < n; i++) {
328  ptaGetPt(pta1, i, &x, &y);
329  if (y != yp) {
330  numaAddNumber(na1, i);
331  numaAddNumber(na2, i - 1);
332  }
333  yp = y;
334  }
335  numaAddNumber(na2, n - 1);
336 
337  /* Sort by increasing x each set with the same y value */
338  ptad = ptaCreate(n);
339  ny = numaGetCount(na1); /* number of distinct y values */
340  for (i = 0, index = 0; i < ny; i++) {
341  numaGetIValue(na1, i, &start);
342  numaGetIValue(na2, i, &end);
343  nx = end - start + 1; /* number of points with current y value */
344  if (nx == 1) {
345  ptaGetPt(pta1, index++, &x, &y);
346  ptaAddPt(ptad, x, y);
347  } else {
348  /* More than 1 point; extract and sort the x values */
349  nax = numaCreate(nx);
350  for (j = 0; j < nx; j++) {
351  ptaGetPt(pta1, index + j, &x, &y);
352  numaAddNumber(nax, x);
353  }
354  nas = numaSort(NULL, nax, L_SORT_INCREASING);
355  /* Add the points with x sorted */
356  for (j = 0; j < nx; j++) {
357  numaGetFValue(nas, j, &val);
358  ptaAddPt(ptad, val, y);
359  }
360  index += nx;
361  numaDestroy(&nax);
362  numaDestroy(&nas);
363  }
364  }
365  numaDestroy(&na1);
366  numaDestroy(&na2);
367  ptaDestroy(&pta1);
368  return ptad;
369 }
370 
371 
386 l_ok
387 ptaEqual(PTA *pta1,
388  PTA *pta2,
389  l_int32 *psame)
390 {
391 l_int32 i, n1, n2;
392 l_float32 x1, y1, x2, y2;
393 PTA *ptas1, *ptas2;
394 
395  if (!psame)
396  return ERROR_INT("&same not defined", __func__, 1);
397  *psame = 0.0;
398  if (!pta1 || !pta2)
399  return ERROR_INT("pta1 and pta2 not both defined", __func__, 1);
400 
401  n1 = ptaGetCount(pta1);
402  n2 = ptaGetCount(pta2);
403  if (n1 != n2) return 0;
404 
405  /* 2d sort each and compare */
406  ptas1 = ptaSort2d(pta1);
407  ptas2 = ptaSort2d(pta2);
408  for (i = 0; i < n1; i++) {
409  ptaGetPt(ptas1, i, &x1, &y1);
410  ptaGetPt(ptas2, i, &x2, &y2);
411  if (x1 != x2 || y1 != y2) {
412  ptaDestroy(&ptas1);
413  ptaDestroy(&ptas2);
414  return 0;
415  }
416  }
417 
418  *psame = 1;
419  ptaDestroy(&ptas1);
420  ptaDestroy(&ptas2);
421  return 0;
422 }
423 
424 
425 /*---------------------------------------------------------------------*
426  * Set operations using aset (rbtree) *
427  *---------------------------------------------------------------------*/
434 L_ASET *
436 {
437 l_int32 i, n, x, y;
438 l_uint64 hash;
439 L_ASET *set;
440 RB_TYPE key;
441 
442  if (!pta)
443  return (L_ASET *)ERROR_PTR("pta not defined", __func__, NULL);
444 
445  set = l_asetCreate(L_UINT_TYPE);
446  n = ptaGetCount(pta);
447  for (i = 0; i < n; i++) {
448  ptaGetIPt(pta, i, &x, &y);
449  l_hashPtToUint64(x, y, &hash);
450  key.utype = hash;
451  l_asetInsert(set, key);
452  }
453 
454  return set;
455 }
456 
457 
472 l_ok
474  PTA **pptad)
475 {
476 l_int32 i, n, x, y;
477 PTA *ptad;
478 l_uint64 hash;
479 L_ASET *set;
480 RB_TYPE key;
481 
482  if (!pptad)
483  return ERROR_INT("&ptad not defined", __func__, 1);
484  *pptad = NULL;
485  if (!ptas)
486  return ERROR_INT("ptas not defined", __func__, 1);
487 
488  set = l_asetCreate(L_UINT_TYPE);
489  n = ptaGetCount(ptas);
490  ptad = ptaCreate(n);
491  *pptad = ptad;
492  for (i = 0; i < n; i++) {
493  ptaGetIPt(ptas, i, &x, &y);
494  l_hashPtToUint64(x, y, &hash);
495  key.utype = hash;
496  if (!l_asetFind(set, key)) {
497  ptaAddPt(ptad, x, y);
498  l_asetInsert(set, key);
499  }
500  }
501 
502  l_asetDestroy(&set);
503  return 0;
504 }
505 
506 
526 l_ok
528  PTA *pta2,
529  PTA **pptad)
530 {
531 PTA *pta3;
532 
533  if (!pptad)
534  return ERROR_INT("&ptad not defined", __func__, 1);
535  *pptad = NULL;
536  if (!pta1)
537  return ERROR_INT("pta1 not defined", __func__, 1);
538  if (!pta2)
539  return ERROR_INT("pta2 not defined", __func__, 1);
540 
541  /* Join */
542  pta3 = ptaCopy(pta1);
543  ptaJoin(pta3, pta2, 0, -1);
544 
545  /* Eliminate duplicates */
546  ptaRemoveDupsByAset(pta3, pptad);
547  ptaDestroy(&pta3);
548  return 0;
549 }
550 
551 
569 l_ok
571  PTA *pta2,
572  PTA **pptad)
573 {
574 l_int32 n1, n2, i, n, x, y;
575 l_uint64 hash;
576 L_ASET *set1, *set2;
577 RB_TYPE key;
578 PTA *pta_small, *pta_big, *ptad;
579 
580  if (!pptad)
581  return ERROR_INT("&ptad not defined", __func__, 1);
582  *pptad = NULL;
583  if (!pta1)
584  return ERROR_INT("pta1 not defined", __func__, 1);
585  if (!pta2)
586  return ERROR_INT("pta2 not defined", __func__, 1);
587 
588  /* Put the elements of the biggest array into a set */
589  n1 = ptaGetCount(pta1);
590  n2 = ptaGetCount(pta2);
591  pta_small = (n1 < n2) ? pta1 : pta2; /* do not destroy pta_small */
592  pta_big = (n1 < n2) ? pta2 : pta1; /* do not destroy pta_big */
593  set1 = l_asetCreateFromPta(pta_big);
594 
595  /* Build up the intersection of points */
596  ptad = ptaCreate(0);
597  *pptad = ptad;
598  n = ptaGetCount(pta_small);
599  set2 = l_asetCreate(L_UINT_TYPE);
600  for (i = 0; i < n; i++) {
601  ptaGetIPt(pta_small, i, &x, &y);
602  l_hashPtToUint64(x, y, &hash);
603  key.utype = hash;
604  if (l_asetFind(set1, key) && !l_asetFind(set2, key)) {
605  ptaAddPt(ptad, x, y);
606  l_asetInsert(set2, key);
607  }
608  }
609 
610  l_asetDestroy(&set1);
611  l_asetDestroy(&set2);
612  return 0;
613 }
614 
615 
616 /*--------------------------------------------------------------------------*
617  * Hashmap operations *
618  *--------------------------------------------------------------------------*/
631 L_HASHMAP *
633 {
634 l_int32 i, n, x, y;
635 l_uint64 key;
636 L_HASHITEM *hitem;
637 L_HASHMAP *hmap;
638 
639  if (!pta)
640  return (L_HASHMAP *)ERROR_PTR("pta not defined", __func__, NULL);
641 
642  n = ptaGetCount(pta);
643  if ((hmap = l_hmapCreate(0.51 * n, 2)) == NULL)
644  return (L_HASHMAP *)ERROR_PTR("hmap not made", __func__, NULL);
645  for (i = 0; i < n; i++) {
646  ptaGetIPt(pta, i, &x, &y);
647  l_hashPtToUint64(x, y, &key);
648  hitem = l_hmapLookup(hmap, key, i, L_HMAP_CREATE);
649  }
650  return hmap;
651 }
652 
653 
667 l_ok
669  PTA **pptad,
670  L_HASHMAP **phmap)
671 {
672 l_int32 i, x, y, tabsize;
673 PTA *ptad;
674 L_HASHITEM *hitem;
675 L_HASHMAP *hmap;
676 
677  if (phmap) *phmap = NULL;
678  if (!pptad)
679  return ERROR_INT("&ptad not defined", __func__, 1);
680  *pptad = NULL;
681  if (!ptas)
682  return ERROR_INT("ptas not defined", __func__, 1);
683 
684  /* Traverse the hashtable lists */
685  if ((hmap = l_hmapCreateFromPta(ptas)) == NULL)
686  return ERROR_INT("hmap not made", __func__, 1);
687  ptad = ptaCreate(0);
688  *pptad = ptad;
689  tabsize = hmap->tabsize;
690  for (i = 0; i < tabsize; i++) {
691  hitem = hmap->hashtab[i];
692  while (hitem) {
693  ptaGetIPt(ptas, hitem->val, &x, &y);
694  ptaAddPt(ptad, x, y);
695  hitem = hitem->next;
696  }
697  }
698 
699  if (phmap)
700  *phmap = hmap;
701  else
702  l_hmapDestroy(&hmap);
703  return 0;
704 }
705 
706 
720 l_ok
722  PTA *pta2,
723  PTA **pptad)
724 {
725 PTA *pta3;
726 
727  if (!pptad)
728  return ERROR_INT("&ptad not defined", __func__, 1);
729  *pptad = NULL;
730  if (!pta1)
731  return ERROR_INT("pta1 not defined", __func__, 1);
732  if (!pta2)
733  return ERROR_INT("pta2 not defined", __func__, 1);
734 
735  pta3 = ptaCopy(pta1);
736  if (ptaJoin(pta3, pta2, 0, -1) == 1) {
737  ptaDestroy(&pta3);
738  return ERROR_INT("pta join failed", __func__, 1);
739  }
740  ptaRemoveDupsByHmap(pta3, pptad, NULL);
741  ptaDestroy(&pta3);
742  return 0;
743 }
744 
745 
759 l_ok
761  PTA *pta2,
762  PTA **pptad)
763 {
764 l_int32 i, n1, n2, n, x, y;
765 l_uint64 key;
766 PTA *pta_small, *pta_big, *ptad;
767 L_HASHITEM *hitem;
768 L_HASHMAP *hmap;
769 
770  if (!pptad)
771  return ERROR_INT("&ptad not defined", __func__, 1);
772  *pptad = NULL;
773  if (!pta1)
774  return ERROR_INT("pta1 not defined", __func__, 1);
775  if (!pta2)
776  return ERROR_INT("pta2 not defined", __func__, 1);
777 
778  /* Make a hashmap for the elements of the biggest array */
779  n1 = ptaGetCount(pta1);
780  n2 = ptaGetCount(pta2);
781  pta_small = (n1 < n2) ? pta1 : pta2; /* do not destroy pta_small */
782  pta_big = (n1 < n2) ? pta2 : pta1; /* do not destroy pta_big */
783  if ((hmap = l_hmapCreateFromPta(pta_big)) == NULL)
784  return ERROR_INT("hmap not made", __func__, 1);
785 
786  /* Go through the smallest array, doing a lookup of its (x,y) into
787  * the big array hashmap. If an hitem is returned, check the count.
788  * If the count is 0, ignore; otherwise, add the point to the
789  * output ptad and set the count in the hitem to 0, indicating
790  * that the point has already been added. */
791  ptad = ptaCreate(0);
792  *pptad = ptad;
793  n = ptaGetCount(pta_small);
794  for (i = 0; i < n; i++) {
795  ptaGetIPt(pta_small, i, &x, &y);
796  l_hashPtToUint64(x, y, &key);
797  hitem = l_hmapLookup(hmap, key, i, L_HMAP_CHECK);
798  if (!hitem || hitem->count == 0)
799  continue;
800  ptaAddPt(ptad, x, y);
801  hitem->count = 0;
802  }
803  l_hmapDestroy(&hmap);
804  return 0;
805 }
806 
807 
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:460
l_ok numaGetFValue(NUMA *na, l_int32 index, l_float32 *pval)
numaGetFValue()
Definition: numabasic.c:687
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:193
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:357
l_int32 numaGetCount(NUMA *na)
numaGetCount()
Definition: numabasic.c:630
l_ok numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition: numabasic.c:720
NUMA * numaSort(NUMA *naout, NUMA *nain, l_int32 sortorder)
numaSort()
Definition: numafunc1.c:2567
NUMA * numaGetSortIndex(NUMA *na, l_int32 sortorder)
numaGetSortIndex()
Definition: numafunc1.c:2664
@ L_SORT_BY_Y
Definition: pix.h:529
@ L_SORT_BY_X
Definition: pix.h:528
@ L_COPY
Definition: pix.h:505
@ L_INSERT
Definition: pix.h:504
@ L_SORT_DECREASING
Definition: pix.h:523
@ L_SORT_INCREASING
Definition: pix.h:522
PTAA * ptaaCreate(l_int32 n)
ptaaCreate()
Definition: ptabasic.c:905
PTA * ptaaGetPta(PTAA *ptaa, l_int32 index, l_int32 accessflag)
ptaaGetPta()
Definition: ptabasic.c:1064
l_ok ptaGetIPt(PTA *pta, l_int32 index, l_int32 *px, l_int32 *py)
ptaGetIPt()
Definition: ptabasic.c:527
l_ok ptaaAddPta(PTAA *ptaa, PTA *pta, l_int32 copyflag)
ptaaAddPta()
Definition: ptabasic.c:963
l_int32 ptaaGetCount(PTAA *ptaa)
ptaaGetCount()
Definition: ptabasic.c:1046
l_ok ptaAddPt(PTA *pta, l_float32 x, l_float32 y)
ptaAddPt()
Definition: ptabasic.c:328
l_ok ptaGetPt(PTA *pta, l_int32 index, l_float32 *px, l_float32 *py)
ptaGetPt()
Definition: ptabasic.c:499
l_int32 ptaGetCount(PTA *pta)
ptaGetCount()
Definition: ptabasic.c:480
PTA * ptaCreate(l_int32 n)
ptaCreate()
Definition: ptabasic.c:120
void ptaDestroy(PTA **ppta)
ptaDestroy()
Definition: ptabasic.c:191
PTA * ptaCopy(PTA *pta)
ptaCopy()
Definition: ptabasic.c:219
l_ok ptaJoin(PTA *ptad, PTA *ptas, l_int32 istart, l_int32 iend)
ptaJoin()
Definition: ptafunc1.c:166
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:721
PTA * ptaSort2d(PTA *pta)
ptaSort2d()
Definition: ptafunc2.c:307
L_ASET * l_asetCreateFromPta(PTA *pta)
l_asetCreateFromPta()
Definition: ptafunc2.c:435
l_ok ptaIntersectionByAset(PTA *pta1, PTA *pta2, PTA **pptad)
ptaIntersectionByAset()
Definition: ptafunc2.c:570
l_ok ptaUnionByAset(PTA *pta1, PTA *pta2, PTA **pptad)
ptaUnionByAset()
Definition: ptafunc2.c:527
PTAA * ptaaSortByIndex(PTAA *ptaas, NUMA *naindex)
ptaaSortByIndex()
Definition: ptafunc2.c:220
l_ok ptaEqual(PTA *pta1, PTA *pta2, l_int32 *psame)
ptaEqual()
Definition: ptafunc2.c:387
l_ok ptaGetRankValue(PTA *pta, l_float32 fract, PTA *ptasort, l_int32 sorttype, l_float32 *pval)
ptaGetRankValue()
Definition: ptafunc2.c:257
l_ok ptaRemoveDupsByAset(PTA *ptas, PTA **pptad)
ptaRemoveDupsByAset()
Definition: ptafunc2.c:473
l_ok ptaIntersectionByHmap(PTA *pta1, PTA *pta2, PTA **pptad)
ptaIntersectionByHmap()
Definition: ptafunc2.c:760
l_ok ptaRemoveDupsByHmap(PTA *ptas, PTA **pptad, L_HASHMAP **phmap)
ptaRemoveDupsByHmap()
Definition: ptafunc2.c:668
L_HASHMAP * l_hmapCreateFromPta(PTA *pta)
l_hmapCreateFromPta()
Definition: ptafunc2.c:632
l_ok ptaGetSortIndex(PTA *ptas, l_int32 sorttype, l_int32 sortorder, NUMA **pnaindex)
ptaGetSortIndex()
Definition: ptafunc2.c:137
PTA * ptaSortByIndex(PTA *ptas, NUMA *naindex)
ptaSortByIndex()
Definition: ptafunc2.c:186
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: rbtree.h:62
l_ok l_hashPtToUint64(l_int32 x, l_int32 y, l_uint64 *phash)
l_hashPtToUint64()
Definition: utils1.c:793