Leptonica 1.85.0
Image processing and image analysis suite
Loading...
Searching...
No Matches
dnafunc1.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#include "array_internal.h"
83
84
85/*----------------------------------------------------------------------*
86 * Rearrangements *
87 *----------------------------------------------------------------------*/
104l_ok
106 L_DNA *das,
107 l_int32 istart,
108 l_int32 iend)
109{
110l_int32 n, i;
111l_float64 val;
112
113 if (!dad)
114 return ERROR_INT("dad not defined", __func__, 1);
115 if (!das)
116 return 0;
117
118 if (istart < 0)
119 istart = 0;
120 n = l_dnaGetCount(das);
121 if (iend < 0 || iend >= n)
122 iend = n - 1;
123 if (istart > iend)
124 return ERROR_INT("istart > iend; nothing to add", __func__, 1);
125
126 for (i = istart; i <= iend; i++) {
127 l_dnaGetDValue(das, i, &val);
128 if (l_dnaAddNumber(dad, val) == 1) {
129 L_ERROR("failed to add double at i = %d\n", __func__, i);
130 return 1;
131 }
132
133 }
134 return 0;
135}
136
137
151L_DNA *
153{
154l_int32 i, nalloc;
155L_DNA *da, *dad;
156L_DNA **array;
157
158 if (!daa)
159 return (L_DNA *)ERROR_PTR("daa not defined", __func__, NULL);
160
161 nalloc = daa->nalloc;
162 array = daa->dna;
163 dad = l_dnaCreate(0);
164 for (i = 0; i < nalloc; i++) {
165 da = array[i];
166 if (!da) continue;
167 l_dnaJoin(dad, da, 0, -1);
168 }
169
170 return dad;
171}
172
173
182L_DNA *
184 l_int32 first,
185 l_int32 last)
186{
187l_int32 n, i;
188l_float64 dval;
189L_DNA *dad;
190
191 if (!das)
192 return (L_DNA *)ERROR_PTR("das not defined", __func__, NULL);
193 if ((n = l_dnaGetCount(das)) == 0) {
194 L_WARNING("das is empty\n", __func__);
195 return l_dnaCopy(das);
196 }
197 first = L_MAX(0, first);
198 if (last < 0) last = n - 1;
199 if (first >= n)
200 return (L_DNA *)ERROR_PTR("invalid first", __func__, NULL);
201 if (last >= n) {
202 L_WARNING("last = %d is beyond max index = %d; adjusting\n",
203 __func__, last, n - 1);
204 last = n - 1;
205 }
206 if (first > last)
207 return (L_DNA *)ERROR_PTR("first > last", __func__, NULL);
208
209 dad = l_dnaCreate(last - first + 1);
210 for (i = first; i <= last; i++) {
211 l_dnaGetDValue(das, i, &dval);
212 l_dnaAddNumber(dad, dval);
213 }
214 return dad;
215}
216
217
218/*----------------------------------------------------------------------*
219 * Conversion between numa and dna *
220 *----------------------------------------------------------------------*/
227NUMA *
229{
230l_int32 i, n;
231l_float64 val;
232NUMA *na;
233
234 if (!da)
235 return (NUMA *)ERROR_PTR("da not defined", __func__, NULL);
236
237 n = l_dnaGetCount(da);
238 na = numaCreate(n);
239 for (i = 0; i < n; i++) {
240 l_dnaGetDValue(da, i, &val);
241 numaAddNumber(na, val);
242 }
243 return na;
244}
245
246
253L_DNA *
255{
256l_int32 i, n;
257l_float32 val;
258L_DNA *da;
259
260 if (!na)
261 return (L_DNA *)ERROR_PTR("na not defined", __func__, NULL);
262
263 n = numaGetCount(na);
264 da = l_dnaCreate(n);
265 for (i = 0; i < n; i++) {
266 numaGetFValue(na, i, &val);
267 l_dnaAddNumber(da, val);
268 }
269 return da;
270}
271
272
273/*----------------------------------------------------------------------*
274 * Conversion from pix data to dna *
275 *----------------------------------------------------------------------*/
287L_DNA *
289{
290l_int32 i, j, w, h, wpl;
291l_uint32 *data, *line;
292L_DNA *da;
293
294 if (!pix)
295 return (L_DNA *)ERROR_PTR("pix not defined", __func__, NULL);
296 if (pixGetDepth(pix) != 32)
297 return (L_DNA *)ERROR_PTR("pix not 32 bpp", __func__, NULL);
298
299 pixGetDimensions(pix, &w, &h, NULL);
300 data = pixGetData(pix);
301 wpl = pixGetWpl(pix);
302 da = l_dnaCreate(w * h);
303 for (i = 0; i < h; i++) {
304 line = data + i * wpl;
305 for (j = 0; j < w; j++)
306 l_dnaAddNumber(da, (l_float64)line[j]);
307 }
308 return da;
309}
310
311
312/*----------------------------------------------------------------------*
313 * Set operations using aset (rbtree) *
314 *----------------------------------------------------------------------*/
321L_ASET *
323{
324l_int32 i, n;
325l_float64 val;
326L_ASET *set;
327RB_TYPE key;
328
329 if (!da)
330 return (L_ASET *)ERROR_PTR("da not defined", __func__, NULL);
331
332 set = l_asetCreate(L_FLOAT_TYPE);
333 n = l_dnaGetCount(da);
334 for (i = 0; i < n; i++) {
335 l_dnaGetDValue(da, i, &val);
336 key.ftype = val;
337 l_asetInsert(set, key);
338 }
339
340 return set;
341}
342
343
351l_ok
353 L_DNA **pdad)
354{
355l_int32 i, n;
356l_float64 val;
357L_DNA *dad;
358L_ASET *set;
359RB_TYPE key;
360
361 if (!pdad)
362 return ERROR_INT("&dad not defined", __func__, 1);
363 *pdad = NULL;
364 if (!das)
365 return ERROR_INT("das not defined", __func__, 1);
366
367 set = l_asetCreate(L_FLOAT_TYPE);
368 dad = l_dnaCreate(0);
369 *pdad = dad;
370 n = l_dnaGetCount(das);
371 for (i = 0; i < n; i++) {
372 l_dnaGetDValue(das, i, &val);
373 key.ftype = val;
374 if (!l_asetFind(set, key)) {
375 l_dnaAddNumber(dad, val);
376 l_asetInsert(set, key);
377 }
378 }
379
380 l_asetDestroy(&set);
381 return 0;
382}
383
384
401l_ok
403 L_DNA *da2,
404 L_DNA **pdad)
405{
406L_DNA *da3;
407
408 if (!pdad)
409 return ERROR_INT("&dad not defined", __func__, 1);
410 if (!da1)
411 return ERROR_INT("da1 not defined", __func__, 1);
412 if (!da2)
413 return ERROR_INT("da2 not defined", __func__, 1);
414
415 /* Join */
416 da3 = l_dnaCopy(da1);
417 if (l_dnaJoin(da3, da2, 0, -1) == 1) {
418 l_dnaDestroy(&da3);
419 return ERROR_INT("join failed for da3", __func__, 1);
420 }
421
422 /* Eliminate duplicates */
423 l_dnaRemoveDupsByAset(da3, pdad);
424 l_dnaDestroy(&da3);
425 return 0;
426}
427
428
445l_ok
447 L_DNA *da2,
448 L_DNA **pdad)
449{
450l_int32 n1, n2, i, n;
451l_float64 val;
452L_ASET *set1, *set2;
453RB_TYPE key;
454L_DNA *da_small, *da_big, *dad;
455
456 if (!pdad)
457 return ERROR_INT("&dad not defined", __func__, 1);
458 *pdad = NULL;
459 if (!da1)
460 return ERROR_INT("&da1 not defined", __func__, 1);
461 if (!da2)
462 return ERROR_INT("&da2 not defined", __func__, 1);
463
464 /* Put the elements of the largest array into a set */
465 n1 = l_dnaGetCount(da1);
466 n2 = l_dnaGetCount(da2);
467 da_small = (n1 < n2) ? da1 : da2; /* do not destroy da_small */
468 da_big = (n1 < n2) ? da2 : da1; /* do not destroy da_big */
469 set1 = l_asetCreateFromDna(da_big);
470
471 /* Build up the intersection of doubles */
472 dad = l_dnaCreate(0);
473 *pdad = dad;
474 n = l_dnaGetCount(da_small);
475 set2 = l_asetCreate(L_FLOAT_TYPE);
476 for (i = 0; i < n; i++) {
477 l_dnaGetDValue(da_small, i, &val);
478 key.ftype = val;
479 if (l_asetFind(set1, key) && !l_asetFind(set2, key)) {
480 l_dnaAddNumber(dad, val);
481 l_asetInsert(set2, key);
482 }
483 }
484
485 l_asetDestroy(&set1);
486 l_asetDestroy(&set2);
487 return 0;
488}
489
490
491/*--------------------------------------------------------------------------*
492 * Hashmap operations *
493 *--------------------------------------------------------------------------*/
507L_HASHMAP *
509{
510l_int32 i, n;
511l_uint64 key;
512l_float64 dval;
513L_HASHMAP *hmap;
514
515 if (!da)
516 return (L_HASHMAP *)ERROR_PTR("da not defined", __func__, NULL);
517
518 n = l_dnaGetCount(da);
519 hmap = l_hmapCreate(0, 0);
520 for (i = 0; i < n; i++) {
521 l_dnaGetDValue(da, i, &dval);
522 l_hashFloat64ToUint64(dval, &key);
523 l_hmapLookup(hmap, key, i, L_HMAP_CREATE);
524 }
525 return hmap;
526}
527
528
543l_ok
545 L_DNA **pdad,
546 L_HASHMAP **phmap)
547{
548l_int32 i, tabsize;
549l_float64 dval;
550L_DNA *dad;
551L_HASHITEM *hitem;
552L_HASHMAP *hmap;
553
554 if (phmap) *phmap = NULL;
555 if (!pdad)
556 return ERROR_INT("&dad not defined", __func__, 1);
557 *pdad = NULL;
558 if (!das)
559 return ERROR_INT("das not defined", __func__, 1);
560
561 /* Traverse the hashtable lists */
562 if ((hmap = l_hmapCreateFromDna(das)) == NULL)
563 return ERROR_INT("hmap not made", __func__, 1);
564 dad = l_dnaCreate(0);
565 *pdad = dad;
566 tabsize = hmap->tabsize;
567 for (i = 0; i < tabsize; i++) {
568 hitem = hmap->hashtab[i];
569 while (hitem) {
570 l_dnaGetDValue(das, hitem->val, &dval);
571 l_dnaAddNumber(dad, dval);
572 hitem = hitem->next;
573 }
574 }
575
576 if (phmap)
577 *phmap = hmap;
578 else
579 l_hmapDestroy(&hmap);
580 return 0;
581}
582
583
597l_ok
599 L_DNA *da2,
600 L_DNA **pdad)
601{
602L_DNA *da3;
603
604 if (!pdad)
605 return ERROR_INT("&dad not defined", __func__, 1);
606 *pdad = NULL;
607 if (!da1)
608 return ERROR_INT("da1 not defined", __func__, 1);
609 if (!da2)
610 return ERROR_INT("da2 not defined", __func__, 1);
611
612 da3 = l_dnaCopy(da1);
613 if (l_dnaJoin(da3, da2, 0, -1) == 1) {
614 l_dnaDestroy(&da3);
615 return ERROR_INT("da3 join failed", __func__, 1);
616 }
617 l_dnaRemoveDupsByHmap(da3, pdad, NULL);
618 l_dnaDestroy(&da3);
619 return 0;
620}
621
622
637l_ok
639 L_DNA *da2,
640 L_DNA **pdad)
641{
642l_int32 i, n1, n2, n;
643l_uint64 key;
644l_float64 dval;
645L_DNA *da_small, *da_big, *dad;
646L_HASHITEM *hitem;
647L_HASHMAP *hmap;
648
649 if (!pdad)
650 return ERROR_INT("&dad not defined", __func__, 1);
651 *pdad = NULL;
652 if (!da1)
653 return ERROR_INT("da1 not defined", __func__, 1);
654 if (!da2)
655 return ERROR_INT("da2 not defined", __func__, 1);
656
657 /* Make a hashmap for the elements of the biggest array */
658 n1 = l_dnaGetCount(da1);
659 n2 = l_dnaGetCount(da2);
660 da_small = (n1 < n2) ? da1 : da2; /* do not destroy da_small */
661 da_big = (n1 < n2) ? da2 : da1; /* do not destroy da_big */
662 if ((hmap = l_hmapCreateFromDna(da_big)) == NULL)
663 return ERROR_INT("hmap not made", __func__, 1);
664
665 /* Go through the smallest array, doing a lookup of its dval into
666 * the big array hashmap. If an hitem is returned, check the count.
667 * If the count is 0, ignore; otherwise, add the dval to the
668 * output dad and set the count in the hitem to 0, indicating
669 * that the dval has already been added. */
670 dad = l_dnaCreate(0);
671 *pdad = dad;
672 n = l_dnaGetCount(da_small);
673 for (i = 0; i < n; i++) {
674 l_dnaGetDValue(da_small, i, &dval);
675 l_hashFloat64ToUint64(dval, &key);
676 hitem = l_hmapLookup(hmap, key, i, L_HMAP_CHECK);
677 if (!hitem || hitem->count == 0)
678 continue;
679 l_dnaAddNumber(dad, dval);
680 hitem->count = 0;
681 }
682 l_hmapDestroy(&hmap);
683 return 0;
684}
685
686
701l_ok
703 L_DNA **pdav,
704 L_DNA **pdac)
705{
706l_int32 i, tabsize;
707l_float64 dval;
708L_DNA *dac, *dav;
709L_HASHITEM *hitem;
710L_HASHMAP *hmap;
711
712 if (pdav) *pdav = NULL;
713 if (pdac) *pdac = NULL;
714 if (!das)
715 return ERROR_INT("das not defined", __func__, 1);
716 if (!pdav)
717 return ERROR_INT("&dav not defined", __func__, 1);
718 if (!pdac)
719 return ERROR_INT("&dac not defined", __func__, 1);
720
721 /* Traverse the hashtable lists */
722 if ((hmap = l_hmapCreateFromDna(das)) == NULL)
723 return ERROR_INT("hmap not made", __func__, 1);
724 dav = l_dnaCreate(0);
725 *pdav = dav;
726 dac = l_dnaCreate(0);
727 *pdac = dac;
728 tabsize = hmap->tabsize;
729 for (i = 0; i < tabsize; i++) {
730 hitem = hmap->hashtab[i];
731 while (hitem) {
732 l_dnaGetDValue(das, hitem->val, &dval);
733 l_dnaAddNumber(dav, dval);
734 l_dnaAddNumber(dac, hitem->count);
735 hitem = hitem->next;
736 }
737 }
738
739 l_hmapDestroy(&hmap);
740 return 0;
741}
742
743
744/*----------------------------------------------------------------------*
745 * Miscellaneous operations *
746 *----------------------------------------------------------------------*/
754L_DNA *
756{
757l_int32 i, n, prev, cur;
758L_DNA *dad;
759
760 if (!das)
761 return (L_DNA *)ERROR_PTR("das not defined", __func__, NULL);
762 n = l_dnaGetCount(das);
763 dad = l_dnaCreate(n - 1);
764 prev = 0;
765 for (i = 1; i < n; i++) {
766 l_dnaGetIValue(das, i, &cur);
767 l_dnaAddNumber(dad, cur - prev);
768 prev = cur;
769 }
770 return dad;
771}
772
l_ok l_dnaUnionByAset(L_DNA *da1, L_DNA *da2, L_DNA **pdad)
l_dnaUnionByAset()
Definition dnafunc1.c:402
L_ASET * l_asetCreateFromDna(L_DNA *da)
l_asetCreateFromDna()
Definition dnafunc1.c:322
l_ok l_dnaUnionByHmap(L_DNA *da1, L_DNA *da2, L_DNA **pdad)
l_dnaUnionByHmap()
Definition dnafunc1.c:598
L_DNA * l_dnaDiffAdjValues(L_DNA *das)
l_dnaDiffAdjValues()
Definition dnafunc1.c:755
L_DNA * pixConvertDataToDna(PIX *pix)
pixConvertDataToDna()
Definition dnafunc1.c:288
l_ok l_dnaJoin(L_DNA *dad, L_DNA *das, l_int32 istart, l_int32 iend)
l_dnaJoin()
Definition dnafunc1.c:105
L_DNA * l_dnaaFlattenToDna(L_DNAA *daa)
l_dnaaFlattenToDna()
Definition dnafunc1.c:152
l_ok l_dnaMakeHistoByHmap(L_DNA *das, L_DNA **pdav, L_DNA **pdac)
l_dnaMakeHistoByHmap()
Definition dnafunc1.c:702
l_ok l_dnaRemoveDupsByHmap(L_DNA *das, L_DNA **pdad, L_HASHMAP **phmap)
l_dnaRemoveDupsByHmap()
Definition dnafunc1.c:544
L_DNA * l_dnaSelectRange(L_DNA *das, l_int32 first, l_int32 last)
l_dnaSelectRange()
Definition dnafunc1.c:183
NUMA * l_dnaConvertToNuma(L_DNA *da)
l_dnaConvertToNuma()
Definition dnafunc1.c:228
l_ok l_dnaRemoveDupsByAset(L_DNA *das, L_DNA **pdad)
l_dnaRemoveDupsByAset()
Definition dnafunc1.c:352
L_DNA * numaConvertToDna(NUMA *na)
numaConvertToDna
Definition dnafunc1.c:254
L_HASHMAP * l_hmapCreateFromDna(L_DNA *da)
l_hmapCreateFromDna()
Definition dnafunc1.c:508
l_ok l_dnaIntersectionByAset(L_DNA *da1, L_DNA *da2, L_DNA **pdad)
l_dnaIntersectionByAset()
Definition dnafunc1.c:446
l_ok l_dnaIntersectionByHmap(L_DNA *da1, L_DNA *da2, L_DNA **pdad)
l_dnaIntersectionByHmap()
Definition dnafunc1.c:638
l_int32 nalloc
struct L_Dna ** dna
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