Leptonica 1.82.0
Image processing and image analysis suite
sel1.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
27
142#ifdef HAVE_CONFIG_H
143#include <config_auto.h>
144#endif /* HAVE_CONFIG_H */
145
146#include <string.h>
147#include "allheaders.h"
148
149 /* Bounds on sel ptr array size */
150static const l_uint32 MaxPtrArraySize = 10000;
151static const l_int32 InitialPtrArraySize = 50;
153 /* Bounds on kernel size */
154static const l_uint32 MaxKernelSize = 10000;
155
156 /* Bounds on pix template size */
157static const l_uint32 MaxPixTemplateSize = 100;
158static const l_uint32 MaxPixTemplateHits = 1000;
159
160 /* Static functions */
161static l_int32 selaExtendArray(SELA *sela);
162static SEL *selCreateFromSArray(SARRAY *sa, l_int32 first, l_int32 last);
163
165{
166 l_int32 size;
167 l_int32 size1;
168 l_int32 size2;
169 char selnameh1[20];
170 char selnameh2[20];
171 char selnamev1[20];
172 char selnamev2[20];
173};
174
175static const struct CompParameterMap comp_parameter_map[] =
176 { { 2, 2, 1, "sel_2h", "", "sel_2v", "" },
177 { 3, 3, 1, "sel_3h", "", "sel_3v", "" },
178 { 4, 2, 2, "sel_2h", "sel_comb_4h", "sel_2v", "sel_comb_4v" },
179 { 5, 5, 1, "sel_5h", "", "sel_5v", "" },
180 { 6, 3, 2, "sel_3h", "sel_comb_6h", "sel_3v", "sel_comb_6v" },
181 { 7, 7, 1, "sel_7h", "", "sel_7v", "" },
182 { 8, 4, 2, "sel_4h", "sel_comb_8h", "sel_4v", "sel_comb_8v" },
183 { 9, 3, 3, "sel_3h", "sel_comb_9h", "sel_3v", "sel_comb_9v" },
184 { 10, 5, 2, "sel_5h", "sel_comb_10h", "sel_5v", "sel_comb_10v" },
185 { 11, 4, 3, "sel_4h", "sel_comb_12h", "sel_4v", "sel_comb_12v" },
186 { 12, 4, 3, "sel_4h", "sel_comb_12h", "sel_4v", "sel_comb_12v" },
187 { 13, 4, 3, "sel_4h", "sel_comb_12h", "sel_4v", "sel_comb_12v" },
188 { 14, 7, 2, "sel_7h", "sel_comb_14h", "sel_7v", "sel_comb_14v" },
189 { 15, 5, 3, "sel_5h", "sel_comb_15h", "sel_5v", "sel_comb_15v" },
190 { 16, 4, 4, "sel_4h", "sel_comb_16h", "sel_4v", "sel_comb_16v" },
191 { 17, 4, 4, "sel_4h", "sel_comb_16h", "sel_4v", "sel_comb_16v" },
192 { 18, 6, 3, "sel_6h", "sel_comb_18h", "sel_6v", "sel_comb_18v" },
193 { 19, 5, 4, "sel_5h", "sel_comb_20h", "sel_5v", "sel_comb_20v" },
194 { 20, 5, 4, "sel_5h", "sel_comb_20h", "sel_5v", "sel_comb_20v" },
195 { 21, 7, 3, "sel_7h", "sel_comb_21h", "sel_7v", "sel_comb_21v" },
196 { 22, 11, 2, "sel_11h", "sel_comb_22h", "sel_11v", "sel_comb_22v" },
197 { 23, 6, 4, "sel_6h", "sel_comb_24h", "sel_6v", "sel_comb_24v" },
198 { 24, 6, 4, "sel_6h", "sel_comb_24h", "sel_6v", "sel_comb_24v" },
199 { 25, 5, 5, "sel_5h", "sel_comb_25h", "sel_5v", "sel_comb_25v" },
200 { 26, 5, 5, "sel_5h", "sel_comb_25h", "sel_5v", "sel_comb_25v" },
201 { 27, 9, 3, "sel_9h", "sel_comb_27h", "sel_9v", "sel_comb_27v" },
202 { 28, 7, 4, "sel_7h", "sel_comb_28h", "sel_7v", "sel_comb_28v" },
203 { 29, 6, 5, "sel_6h", "sel_comb_30h", "sel_6v", "sel_comb_30v" },
204 { 30, 6, 5, "sel_6h", "sel_comb_30h", "sel_6v", "sel_comb_30v" },
205 { 31, 6, 5, "sel_6h", "sel_comb_30h", "sel_6v", "sel_comb_30v" },
206 { 32, 8, 4, "sel_8h", "sel_comb_32h", "sel_8v", "sel_comb_32v" },
207 { 33, 11, 3, "sel_11h", "sel_comb_33h", "sel_11v", "sel_comb_33v" },
208 { 34, 7, 5, "sel_7h", "sel_comb_35h", "sel_7v", "sel_comb_35v" },
209 { 35, 7, 5, "sel_7h", "sel_comb_35h", "sel_7v", "sel_comb_35v" },
210 { 36, 6, 6, "sel_6h", "sel_comb_36h", "sel_6v", "sel_comb_36v" },
211 { 37, 6, 6, "sel_6h", "sel_comb_36h", "sel_6v", "sel_comb_36v" },
212 { 38, 6, 6, "sel_6h", "sel_comb_36h", "sel_6v", "sel_comb_36v" },
213 { 39, 13, 3, "sel_13h", "sel_comb_39h", "sel_13v", "sel_comb_39v" },
214 { 40, 8, 5, "sel_8h", "sel_comb_40h", "sel_8v", "sel_comb_40v" },
215 { 41, 7, 6, "sel_7h", "sel_comb_42h", "sel_7v", "sel_comb_42v" },
216 { 42, 7, 6, "sel_7h", "sel_comb_42h", "sel_7v", "sel_comb_42v" },
217 { 43, 7, 6, "sel_7h", "sel_comb_42h", "sel_7v", "sel_comb_42v" },
218 { 44, 11, 4, "sel_11h", "sel_comb_44h", "sel_11v", "sel_comb_44v" },
219 { 45, 9, 5, "sel_9h", "sel_comb_45h", "sel_9v", "sel_comb_45v" },
220 { 46, 9, 5, "sel_9h", "sel_comb_45h", "sel_9v", "sel_comb_45v" },
221 { 47, 8, 6, "sel_8h", "sel_comb_48h", "sel_8v", "sel_comb_48v" },
222 { 48, 8, 6, "sel_8h", "sel_comb_48h", "sel_8v", "sel_comb_48v" },
223 { 49, 7, 7, "sel_7h", "sel_comb_49h", "sel_7v", "sel_comb_49v" },
224 { 50, 10, 5, "sel_10h", "sel_comb_50h", "sel_10v", "sel_comb_50v" },
225 { 51, 10, 5, "sel_10h", "sel_comb_50h", "sel_10v", "sel_comb_50v" },
226 { 52, 13, 4, "sel_13h", "sel_comb_52h", "sel_13v", "sel_comb_52v" },
227 { 53, 9, 6, "sel_9h", "sel_comb_54h", "sel_9v", "sel_comb_54v" },
228 { 54, 9, 6, "sel_9h", "sel_comb_54h", "sel_9v", "sel_comb_54v" },
229 { 55, 11, 5, "sel_11h", "sel_comb_55h", "sel_11v", "sel_comb_55v" },
230 { 56, 8, 7, "sel_8h", "sel_comb_56h", "sel_8v", "sel_comb_56v" },
231 { 57, 8, 7, "sel_8h", "sel_comb_56h", "sel_8v", "sel_comb_56v" },
232 { 58, 8, 7, "sel_8h", "sel_comb_56h", "sel_8v", "sel_comb_56v" },
233 { 59, 10, 6, "sel_10h", "sel_comb_60h", "sel_10v", "sel_comb_60v" },
234 { 60, 10, 6, "sel_10h", "sel_comb_60h", "sel_10v", "sel_comb_60v" },
235 { 61, 10, 6, "sel_10h", "sel_comb_60h", "sel_10v", "sel_comb_60v" },
236 { 62, 9, 7, "sel_9h", "sel_comb_63h", "sel_9v", "sel_comb_63v" },
237 { 63, 9, 7, "sel_9h", "sel_comb_63h", "sel_9v", "sel_comb_63v" } };
238
239
240
241/*------------------------------------------------------------------------*
242 * Create / Destroy / Copy *
243 *------------------------------------------------------------------------*/
250SELA *
251selaCreate(l_int32 n)
252{
253SELA *sela;
254
255 PROCNAME("selaCreate");
256
257 if (n <= 0 || n > MaxPtrArraySize)
259
260 /* Make array of sel ptrs */
261 sela = (SELA *)LEPT_CALLOC(1, sizeof(SELA));
262 sela->nalloc = n;
263 sela->n = 0;
264 sela->sel = (SEL **)LEPT_CALLOC(n, sizeof(SEL *));
265 return sela;
266}
267
268
275void
277{
278SELA *sela;
279l_int32 i;
280
281 if (!psela) return;
282 if ((sela = *psela) == NULL)
283 return;
284
285 for (i = 0; i < sela->n; i++)
286 selDestroy(&sela->sel[i]);
287 LEPT_FREE(sela->sel);
288 LEPT_FREE(sela);
289 *psela = NULL;
290}
291
292
309SEL *
310selCreate(l_int32 height,
311 l_int32 width,
312 const char *name)
313{
314SEL *sel;
315
316 PROCNAME("selCreate");
317
318 sel = (SEL *)LEPT_CALLOC(1, sizeof(SEL));
319 if (name)
320 sel->name = stringNew(name);
321 sel->sy = height;
322 sel->sx = width;
323 if ((sel->data = create2dIntArray(height, width)) == NULL) {
324 LEPT_FREE(sel->name);
325 LEPT_FREE(sel);
326 return (SEL *)ERROR_PTR("data not allocated", procName, NULL);
327 }
328
329 return sel;
330}
331
332
339void
340selDestroy(SEL **psel)
341{
342l_int32 i;
343SEL *sel;
344
345 PROCNAME("selDestroy");
346
347 if (psel == NULL) {
348 L_WARNING("ptr address is NULL!\n", procName);
349 return;
350 }
351 if ((sel = *psel) == NULL)
352 return;
353
354 for (i = 0; i < sel->sy; i++)
355 LEPT_FREE(sel->data[i]);
356 LEPT_FREE(sel->data);
357 if (sel->name)
358 LEPT_FREE(sel->name);
359 LEPT_FREE(sel);
360 *psel = NULL;
361}
362
363
370SEL *
371selCopy(SEL *sel)
372{
373l_int32 sx, sy, cx, cy, i, j;
374SEL *csel;
375
376 PROCNAME("selCopy");
377
378 if (!sel)
379 return (SEL *)ERROR_PTR("sel not defined", procName, NULL);
380
381 csel = (SEL *)LEPT_CALLOC(1, sizeof(SEL));
382 selGetParameters(sel, &sy, &sx, &cy, &cx);
383 csel->sy = sy;
384 csel->sx = sx;
385 csel->cy = cy;
386 csel->cx = cx;
387
388 if ((csel->data = create2dIntArray(sy, sx)) == NULL) {
389 LEPT_FREE(csel);
390 return (SEL *)ERROR_PTR("sel data not made", procName, NULL);
391 }
392
393 for (i = 0; i < sy; i++)
394 for (j = 0; j < sx; j++)
395 csel->data[i][j] = sel->data[i][j];
396
397 if (sel->name)
398 csel->name = stringNew(sel->name);
399
400 return csel;
401}
402
403
417SEL *
419 l_int32 w,
420 l_int32 cy,
421 l_int32 cx,
422 l_int32 type)
423{
424l_int32 i, j;
425SEL *sel;
426
427 PROCNAME("selCreateBrick");
428
429 if (h <= 0 || w <= 0)
430 return (SEL *)ERROR_PTR("h and w must both be > 0", procName, NULL);
431 if (type != SEL_HIT && type != SEL_MISS && type != SEL_DONT_CARE)
432 return (SEL *)ERROR_PTR("invalid sel element type", procName, NULL);
433
434 if ((sel = selCreate(h, w, NULL)) == NULL)
435 return (SEL *)ERROR_PTR("sel not made", procName, NULL);
436 selSetOrigin(sel, cy, cx);
437 for (i = 0; i < h; i++)
438 for (j = 0; j < w; j++)
439 sel->data[i][j] = type;
440
441 return sel;
442}
443
444
461SEL *
462selCreateComb(l_int32 factor1,
463 l_int32 factor2,
464 l_int32 direction)
465{
466l_int32 i, size, z;
467SEL *sel;
468
469 PROCNAME("selCreateComb");
470
471 if (factor1 < 1 || factor2 < 1)
472 return (SEL *)ERROR_PTR("factors must be >= 1", procName, NULL);
473 if (direction != L_HORIZ && direction != L_VERT)
474 return (SEL *)ERROR_PTR("invalid direction", procName, NULL);
475
476 size = factor1 * factor2;
477 if (direction == L_HORIZ) {
478 if ((sel = selCreate(1, size, NULL)) == NULL)
479 return (SEL *)ERROR_PTR("horiz sel not made", procName, NULL);
480 selSetOrigin(sel, 0, size / 2);
481 } else {
482 if ((sel = selCreate(size, 1, NULL)) == NULL)
483 return (SEL *)ERROR_PTR("vert sel not made", procName, NULL);
484 selSetOrigin(sel, size / 2, 0);
485 }
486
487 /* Lay down the elements of the comb */
488 for (i = 0; i < factor2; i++) {
489 z = factor1 / 2 + i * factor1;
490/* lept_stderr("i = %d, factor1 = %d, factor2 = %d, z = %d\n",
491 i, factor1, factor2, z); */
492 if (direction == L_HORIZ)
493 selSetElement(sel, 0, z, SEL_HIT);
494 else
495 selSetElement(sel, z, 0, SEL_HIT);
496 }
497
498 return sel;
499}
500
501
516l_int32 **
518 l_int32 sx)
519{
520l_int32 i;
521l_int32 **array;
522
523 PROCNAME("create2dIntArray");
524
525 if (sx <= 0 || sx > MaxKernelSize)
526 return (l_int32 **)ERROR_PTR("sx out of bounds", procName, NULL);
527 if (sy <= 0 || sy > MaxKernelSize)
528 return (l_int32 **)ERROR_PTR("sy out of bounds", procName, NULL);
529
530 array = (l_int32 **)LEPT_CALLOC(sy, sizeof(l_int32 *));
531 for (i = 0; i < sy; i++)
532 array[i] = (l_int32 *)LEPT_CALLOC(sx, sizeof(l_int32));
533 return array;
534}
535
536
537/*------------------------------------------------------------------------*
538 * Extension of sela *
539 *------------------------------------------------------------------------*/
558l_ok
560 SEL *sel,
561 const char *selname,
562 l_int32 copyflag)
563{
564l_int32 n;
565SEL *csel;
566
567 PROCNAME("selaAddSel");
568
569 if (!sela)
570 return ERROR_INT("sela not defined", procName, 1);
571 if (!sel)
572 return ERROR_INT("sel not defined", procName, 1);
573 if (!sel->name && !selname)
574 return ERROR_INT("added sel must have name", procName, 1);
575 if (copyflag != L_INSERT && copyflag != L_COPY)
576 return ERROR_INT("invalid copyflag", procName, 1);
577
578 if (copyflag == L_COPY) {
579 if ((csel = selCopy(sel)) == NULL)
580 return ERROR_INT("csel not made", procName, 1);
581 } else { /* copyflag == L_INSERT */
582 csel = sel;
583 }
584 if (!csel->name)
585 csel->name = stringNew(selname);
586
587 n = selaGetCount(sela);
588 if (n >= sela->nalloc) {
589 if (selaExtendArray(sela)) {
590 if (copyflag != L_INSERT)
591 selDestroy(&csel);
592 return ERROR_INT("extension failed", procName, 1);
593 }
594 }
595
596 sela->sel[n] = csel;
597 sela->n++;
598 return 0;
599}
600
601
608static l_int32
610{
611 PROCNAME("selaExtendArray");
612
613 if (!sela)
614 return ERROR_INT("sela not defined", procName, 1);
615
616 if ((sela->sel = (SEL **)reallocNew((void **)&sela->sel,
617 sizeof(SEL *) * sela->nalloc,
618 2 * sizeof(SEL *) * sela->nalloc)) == NULL)
619 return ERROR_INT("new ptr array not returned", procName, 1);
620
621 sela->nalloc = 2 * sela->nalloc;
622 return 0;
623}
624
625
626
627/*----------------------------------------------------------------------*
628 * Accessors *
629 *----------------------------------------------------------------------*/
636l_int32
638{
639 PROCNAME("selaGetCount");
640
641 if (!sela)
642 return ERROR_INT("sela not defined", procName, 0);
643
644 return sela->n;
645}
646
647
661SEL *
663 l_int32 i)
664{
665 PROCNAME("selaGetSel");
666
667 if (!sela)
668 return (SEL *)ERROR_PTR("sela not defined", procName, NULL);
669
670 if (i < 0 || i >= sela->n)
671 return (SEL *)ERROR_PTR("invalid index", procName, NULL);
672 return sela->sel[i];
673}
674
675
682char *
683selGetName(SEL *sel)
684{
685 PROCNAME("selGetName");
686
687 if (!sel)
688 return (char *)ERROR_PTR("sel not defined", procName, NULL);
689
690 return sel->name;
691}
692
693
707l_ok
708selSetName(SEL *sel,
709 const char *name)
710{
711 PROCNAME("selSetName");
712
713 if (!sel)
714 return ERROR_INT("sel not defined", procName, 1);
715
716 return stringReplace(&sel->name, name);
717}
718
719
729l_ok
731 const char *name,
732 l_int32 *pindex,
733 SEL **psel)
734{
735l_int32 i, n;
736char *sname;
737SEL *sel;
738
739 PROCNAME("selaFindSelByName");
740
741 if (pindex) *pindex = -1;
742 if (psel) *psel = NULL;
743
744 if (!sela)
745 return ERROR_INT("sela not defined", procName, 1);
746
747 n = selaGetCount(sela);
748 for (i = 0; i < n; i++)
749 {
750 if ((sel = selaGetSel(sela, i)) == NULL) {
751 L_WARNING("missing sel\n", procName);
752 continue;
753 }
754
755 sname = selGetName(sel);
756 if (sname && (!strcmp(name, sname))) {
757 if (pindex)
758 *pindex = i;
759 if (psel)
760 *psel = sel;
761 return 0;
762 }
763 }
764
765 return 1;
766}
767
768
778l_ok
780 l_int32 row,
781 l_int32 col,
782 l_int32 *ptype)
783{
784 PROCNAME("selGetElement");
785
786 if (!ptype)
787 return ERROR_INT("&type not defined", procName, 1);
788 *ptype = SEL_DONT_CARE;
789 if (!sel)
790 return ERROR_INT("sel not defined", procName, 1);
791 if (row < 0 || row >= sel->sy)
792 return ERROR_INT("sel row out of bounds", procName, 1);
793 if (col < 0 || col >= sel->sx)
794 return ERROR_INT("sel col out of bounds", procName, 1);
795
796 *ptype = sel->data[row][col];
797 return 0;
798}
799
800
818l_ok
820 l_int32 row,
821 l_int32 col,
822 l_int32 type)
823{
824 PROCNAME("selSetElement");
825
826 if (!sel)
827 return ERROR_INT("sel not defined", procName, 1);
828 if (type != SEL_HIT && type != SEL_MISS && type != SEL_DONT_CARE)
829 return ERROR_INT("invalid sel element type", procName, 1);
830 if (row < 0 || row >= sel->sy)
831 return ERROR_INT("sel row out of bounds", procName, 1);
832 if (col < 0 || col >= sel->sx)
833 return ERROR_INT("sel col out of bounds", procName, 1);
834
835 sel->data[row][col] = type;
836 return 0;
837}
838
839
847l_ok
849 l_int32 *psy,
850 l_int32 *psx,
851 l_int32 *pcy,
852 l_int32 *pcx)
853{
854 PROCNAME("selGetParameters");
855
856 if (psy) *psy = 0;
857 if (psx) *psx = 0;
858 if (pcy) *pcy = 0;
859 if (pcx) *pcx = 0;
860 if (!sel)
861 return ERROR_INT("sel not defined", procName, 1);
862 if (psy) *psy = sel->sy;
863 if (psx) *psx = sel->sx;
864 if (pcy) *pcy = sel->cy;
865 if (pcx) *pcx = sel->cx;
866 return 0;
867}
868
869
877l_ok
879 l_int32 cy,
880 l_int32 cx)
881{
882 PROCNAME("selSetOrigin");
883
884 if (!sel)
885 return ERROR_INT("sel not defined", procName, 1);
886 sel->cy = cy;
887 sel->cx = cx;
888 return 0;
889}
890
891
899l_ok
901 l_int32 *ptype)
902{
903l_int32 sx, sy, cx, cy, i, j;
904
905 PROCNAME("selGetTypeAtOrigin");
906
907 if (!ptype)
908 return ERROR_INT("&type not defined", procName, 1);
909 *ptype = SEL_DONT_CARE; /* init */
910 if (!sel)
911 return ERROR_INT("sel not defined", procName, 1);
912
913 selGetParameters(sel, &sy, &sx, &cy, &cx);
914 for (i = 0; i < sy; i++) {
915 for (j = 0; j < sx; j++) {
916 if (i == cy && j == cx) {
917 selGetElement(sel, i, j, ptype);
918 return 0;
919 }
920 }
921 }
922
923 return ERROR_INT("sel origin not found", procName, 1);
924}
925
926
934char *
936 l_int32 hsize,
937 l_int32 vsize)
938{
939l_int32 i, nsels, sx, sy;
940SEL *sel;
941
942 PROCNAME("selaGetBrickName");
943
944 if (!sela)
945 return (char *)ERROR_PTR("sela not defined", procName, NULL);
946
947 nsels = selaGetCount(sela);
948 for (i = 0; i < nsels; i++) {
949 sel = selaGetSel(sela, i);
950 selGetParameters(sel, &sy, &sx, NULL, NULL);
951 if (hsize == sx && vsize == sy)
952 return stringNew(selGetName(sel));
953 }
954
955 return (char *)ERROR_PTR("sel not found", procName, NULL);
956}
957
958
973char *
975 l_int32 size,
976 l_int32 direction)
977{
978char *selname;
979char combname[256];
980l_int32 i, nsels, sx, sy, found;
981SEL *sel;
982
983 PROCNAME("selaGetCombName");
984
985 if (!sela)
986 return (char *)ERROR_PTR("sela not defined", procName, NULL);
987 if (direction != L_HORIZ && direction != L_VERT)
988 return (char *)ERROR_PTR("invalid direction", procName, NULL);
989
990 /* Derive the comb name we're looking for */
991 if (direction == L_HORIZ)
992 snprintf(combname, sizeof(combname), "sel_comb_%dh", size);
993 else /* direction == L_VERT */
994 snprintf(combname, sizeof(combname), "sel_comb_%dv", size);
995
996 found = FALSE;
997 nsels = selaGetCount(sela);
998 for (i = 0; i < nsels; i++) {
999 sel = selaGetSel(sela, i);
1000 selGetParameters(sel, &sy, &sx, NULL, NULL);
1001 if (sy != 1 && sx != 1) /* 2-D; not a comb */
1002 continue;
1003 selname = selGetName(sel);
1004 if (!strcmp(selname, combname)) {
1005 found = TRUE;
1006 break;
1007 }
1008 }
1009
1010 if (found)
1011 return stringNew(selname);
1012 else
1013 return (char *)ERROR_PTR("sel not found", procName, NULL);
1014}
1015
1016
1017/* --------- Function used to generate code in this file ---------- */
1018#if 0
1019static void selaComputeCompositeParameters(const char *fileout);
1020
1038static void
1039selaComputeCompositeParameters(const char *fileout)
1040{
1041char *str, *nameh1, *nameh2, *namev1, *namev2;
1042char buf[256];
1043l_int32 size, size1, size2, len;
1044SARRAY *sa;
1045SELA *selabasic, *selacomb;
1046
1047 selabasic = selaAddBasic(NULL);
1048 selacomb = selaAddDwaCombs(NULL);
1049 sa = sarrayCreate(64);
1050 for (size = 2; size < 64; size++) {
1051 selectComposableSizes(size, &size1, &size2);
1052 nameh1 = selaGetBrickName(selabasic, size1, 1);
1053 namev1 = selaGetBrickName(selabasic, 1, size1);
1054 if (size2 > 1) {
1055 nameh2 = selaGetCombName(selacomb, size1 * size2, L_HORIZ);
1056 namev2 = selaGetCombName(selacomb, size1 * size2, L_VERT);
1057 } else {
1058 nameh2 = stringNew("");
1059 namev2 = stringNew("");
1060 }
1061 snprintf(buf, sizeof(buf),
1062 " { %d, %d, %d, \"%s\", \"%s\", \"%s\", \"%s\" },",
1063 size, size1, size2, nameh1, nameh2, namev1, namev2);
1064 sarrayAddString(sa, buf, L_COPY);
1065 LEPT_FREE(nameh1);
1066 LEPT_FREE(nameh2);
1067 LEPT_FREE(namev1);
1068 LEPT_FREE(namev2);
1069 }
1070 str = sarrayToString(sa, 1);
1071 len = strlen(str);
1072 l_binaryWrite(fileout, "w", str, len + 1);
1073 LEPT_FREE(str);
1074 sarrayDestroy(&sa);
1075 selaDestroy(&selabasic);
1076 selaDestroy(&selacomb);
1077}
1078#endif
1079/* -------------------------------------------------------------------- */
1080
1081
1100l_ok
1102 l_int32 *psize1,
1103 l_int32 *psize2,
1104 char **pnameh1,
1105 char **pnameh2,
1106 char **pnamev1,
1107 char **pnamev2)
1108{
1109l_int32 index;
1110
1111 PROCNAME("selaGetSelnames");
1112
1113 if (psize1) *psize1 = 0;
1114 if (psize2) *psize2 = 0;
1115 if (pnameh1) *pnameh1 = NULL;
1116 if (pnameh2) *pnameh2 = NULL;
1117 if (pnamev1) *pnamev1 = NULL;
1118 if (pnamev2) *pnamev2 = NULL;
1119 if (size < 2 || size > 63)
1120 return ERROR_INT("valid size range is {2 ... 63}", procName, 1);
1121 index = size - 2;
1122 if (psize1)
1123 *psize1 = comp_parameter_map[index].size1;
1124 if (psize2)
1125 *psize2 = comp_parameter_map[index].size2;
1126 if (pnameh1)
1127 *pnameh1 = stringNew(comp_parameter_map[index].selnameh1);
1128 if (pnameh2)
1129 *pnameh2 = stringNew(comp_parameter_map[index].selnameh2);
1130 if (pnamev1)
1131 *pnamev1 = stringNew(comp_parameter_map[index].selnamev1);
1132 if (pnamev2)
1133 *pnamev2 = stringNew(comp_parameter_map[index].selnamev2);
1134 return 0;
1135}
1136
1137
1144SARRAY *
1146{
1147char *selname;
1148l_int32 i, n;
1149SEL *sel;
1150SARRAY *sa;
1151
1152 PROCNAME("selaGetSelnames");
1153
1154 if (!sela)
1155 return (SARRAY *)ERROR_PTR("sela not defined", procName, NULL);
1156 if ((n = selaGetCount(sela)) == 0)
1157 return (SARRAY *)ERROR_PTR("no sels in sela", procName, NULL);
1158
1159 if ((sa = sarrayCreate(n)) == NULL)
1160 return (SARRAY *)ERROR_PTR("sa not made", procName, NULL);
1161 for (i = 0; i < n; i++) {
1162 sel = selaGetSel(sela, i);
1163 selname = selGetName(sel);
1164 sarrayAddString(sa, selname, L_COPY);
1165 }
1166
1167 return sa;
1168}
1169
1170
1171
1172/*----------------------------------------------------------------------*
1173 * Max translations for erosion and hmt *
1174 *----------------------------------------------------------------------*/
1189l_ok
1191 l_int32 *pxp,
1192 l_int32 *pyp,
1193 l_int32 *pxn,
1194 l_int32 *pyn)
1195{
1196l_int32 sx, sy, cx, cy, i, j;
1197l_int32 maxxp, maxyp, maxxn, maxyn;
1198
1199 PROCNAME("selaFindMaxTranslations");
1200
1201 if (!pxp || !pyp || !pxn || !pyn)
1202 return ERROR_INT("&xp (etc) defined", procName, 1);
1203 *pxp = *pyp = *pxn = *pyn = 0;
1204 if (!sel)
1205 return ERROR_INT("sel not defined", procName, 1);
1206 selGetParameters(sel, &sy, &sx, &cy, &cx);
1207
1208 maxxp = maxyp = maxxn = maxyn = 0;
1209 for (i = 0; i < sy; i++) {
1210 for (j = 0; j < sx; j++) {
1211 if (sel->data[i][j] == 1) {
1212 maxxp = L_MAX(maxxp, cx - j);
1213 maxyp = L_MAX(maxyp, cy - i);
1214 maxxn = L_MAX(maxxn, j - cx);
1215 maxyn = L_MAX(maxyn, i - cy);
1216 }
1217 }
1218 }
1219
1220 *pxp = maxxp;
1221 *pyp = maxyp;
1222 *pxn = maxxn;
1223 *pyn = maxyn;
1224
1225 return 0;
1226}
1227
1228
1229/*----------------------------------------------------------------------*
1230 * Rotation by multiples of 90 degrees *
1231 *----------------------------------------------------------------------*/
1239SEL *
1241 l_int32 quads)
1242{
1243l_int32 i, j, ni, nj, sx, sy, cx, cy, nsx, nsy, ncx, ncy, type;
1244SEL *seld;
1245
1246 PROCNAME("selRotateOrth");
1247
1248 if (!sel)
1249 return (SEL *)ERROR_PTR("sel not defined", procName, NULL);
1250 if (quads < 0 || quads > 4)
1251 return (SEL *)ERROR_PTR("quads not in {0,1,2,3,4}", procName, NULL);
1252 if (quads == 0 || quads == 4)
1253 return selCopy(sel);
1254
1255 selGetParameters(sel, &sy, &sx, &cy, &cx);
1256 if (quads == 1) { /* 90 degrees cw */
1257 nsx = sy;
1258 nsy = sx;
1259 ncx = sy - cy - 1;
1260 ncy = cx;
1261 } else if (quads == 2) { /* 180 degrees cw */
1262 nsx = sx;
1263 nsy = sy;
1264 ncx = sx - cx - 1;
1265 ncy = sy - cy - 1;
1266 } else { /* 270 degrees cw */
1267 nsx = sy;
1268 nsy = sx;
1269 ncx = cy;
1270 ncy = sx - cx - 1;
1271 }
1272 seld = selCreateBrick(nsy, nsx, ncy, ncx, SEL_DONT_CARE);
1273 if (sel->name)
1274 seld->name = stringNew(sel->name);
1275
1276 for (i = 0; i < sy; i++) {
1277 for (j = 0; j < sx; j++) {
1278 selGetElement(sel, i, j, &type);
1279 if (quads == 1) {
1280 ni = j;
1281 nj = sy - i - 1;
1282 } else if (quads == 2) {
1283 ni = sy - i - 1;
1284 nj = sx - j - 1;
1285 } else { /* quads == 3 */
1286 ni = sx - j - 1;
1287 nj = i;
1288 }
1289 selSetElement(seld, ni, nj, type);
1290 }
1291 }
1292
1293 return seld;
1294}
1295
1296
1297/*----------------------------------------------------------------------*
1298 * Sela and Sel serialized I/O *
1299 *----------------------------------------------------------------------*/
1306SELA *
1307selaRead(const char *fname)
1308{
1309FILE *fp;
1310SELA *sela;
1311
1312 PROCNAME("selaRead");
1313
1314 if (!fname)
1315 return (SELA *)ERROR_PTR("fname not defined", procName, NULL);
1316
1317 if ((fp = fopenReadStream(fname)) == NULL)
1318 return (SELA *)ERROR_PTR("stream not opened", procName, NULL);
1319 if ((sela = selaReadStream(fp)) == NULL) {
1320 fclose(fp);
1321 return (SELA *)ERROR_PTR("sela not returned", procName, NULL);
1322 }
1323 fclose(fp);
1324
1325 return sela;
1326}
1327
1328
1335SELA *
1337{
1338l_int32 i, n, version;
1339SEL *sel;
1340SELA *sela;
1341
1342 PROCNAME("selaReadStream");
1343
1344 if (!fp)
1345 return (SELA *)ERROR_PTR("stream not defined", procName, NULL);
1346
1347 if (fscanf(fp, "\nSela Version %d\n", &version) != 1)
1348 return (SELA *)ERROR_PTR("not a sela file", procName, NULL);
1349 if (version != SEL_VERSION_NUMBER)
1350 return (SELA *)ERROR_PTR("invalid sel version", procName, NULL);
1351 if (fscanf(fp, "Number of Sels = %d\n\n", &n) != 1)
1352 return (SELA *)ERROR_PTR("not a sela file", procName, NULL);
1353
1354 if ((sela = selaCreate(n)) == NULL)
1355 return (SELA *)ERROR_PTR("sela not made", procName, NULL);
1356 sela->nalloc = n;
1357
1358 for (i = 0; i < n; i++) {
1359 if ((sel = selReadStream(fp)) == NULL) {
1360 selaDestroy(&sela);
1361 return (SELA *)ERROR_PTR("sel not read", procName, NULL);
1362 }
1363 selaAddSel(sela, sel, NULL, 0);
1364 }
1365
1366 return sela;
1367}
1368
1369
1376SEL *
1377selRead(const char *fname)
1378{
1379FILE *fp;
1380SEL *sel;
1381
1382 PROCNAME("selRead");
1383
1384 if (!fname)
1385 return (SEL *)ERROR_PTR("fname not defined", procName, NULL);
1386
1387 if ((fp = fopenReadStream(fname)) == NULL)
1388 return (SEL *)ERROR_PTR("stream not opened", procName, NULL);
1389 if ((sel = selReadStream(fp)) == NULL) {
1390 fclose(fp);
1391 return (SEL *)ERROR_PTR("sela not returned", procName, NULL);
1392 }
1393 fclose(fp);
1394
1395 return sel;
1396}
1397
1398
1405SEL *
1407{
1408char selname[256];
1409char linebuf[256];
1410l_int32 sy, sx, cy, cx, i, j, version, ignore;
1411SEL *sel;
1412
1413 PROCNAME("selReadStream");
1414
1415 if (!fp)
1416 return (SEL *)ERROR_PTR("stream not defined", procName, NULL);
1417
1418 if (fscanf(fp, " Sel Version %d\n", &version) != 1)
1419 return (SEL *)ERROR_PTR("not a sel file", procName, NULL);
1420 if (version != SEL_VERSION_NUMBER)
1421 return (SEL *)ERROR_PTR("invalid sel version", procName, NULL);
1422
1423 if (fgets(linebuf, sizeof(linebuf), fp) == NULL)
1424 return (SEL *)ERROR_PTR("error reading into linebuf", procName, NULL);
1425 sscanf(linebuf, " ------ %200s ------", selname);
1426
1427 if (fscanf(fp, " sy = %d, sx = %d, cy = %d, cx = %d\n",
1428 &sy, &sx, &cy, &cx) != 4)
1429 return (SEL *)ERROR_PTR("dimensions not read", procName, NULL);
1430
1431 if ((sel = selCreate(sy, sx, selname)) == NULL)
1432 return (SEL *)ERROR_PTR("sel not made", procName, NULL);
1433 selSetOrigin(sel, cy, cx);
1434
1435 for (i = 0; i < sy; i++) {
1436 ignore = fscanf(fp, " ");
1437 for (j = 0; j < sx; j++)
1438 ignore = fscanf(fp, "%1d", &sel->data[i][j]);
1439 ignore = fscanf(fp, "\n");
1440 }
1441 ignore = fscanf(fp, "\n");
1442
1443 return sel;
1444}
1445
1446
1454l_ok
1455selaWrite(const char *fname,
1456 SELA *sela)
1457{
1458FILE *fp;
1459
1460 PROCNAME("selaWrite");
1461
1462 if (!fname)
1463 return ERROR_INT("fname not defined", procName, 1);
1464 if (!sela)
1465 return ERROR_INT("sela not defined", procName, 1);
1466
1467 if ((fp = fopenWriteStream(fname, "wb")) == NULL)
1468 return ERROR_INT("stream not opened", procName, 1);
1469 selaWriteStream(fp, sela);
1470 fclose(fp);
1471
1472 return 0;
1473}
1474
1475
1483l_ok
1485 SELA *sela)
1486{
1487l_int32 i, n;
1488SEL *sel;
1489
1490 PROCNAME("selaWriteStream");
1491
1492 if (!fp)
1493 return ERROR_INT("stream not defined", procName, 1);
1494 if (!sela)
1495 return ERROR_INT("sela not defined", procName, 1);
1496
1497 n = selaGetCount(sela);
1498 fprintf(fp, "\nSela Version %d\n", SEL_VERSION_NUMBER);
1499 fprintf(fp, "Number of Sels = %d\n\n", n);
1500 for (i = 0; i < n; i++) {
1501 if ((sel = selaGetSel(sela, i)) == NULL)
1502 continue;
1503 selWriteStream(fp, sel);
1504 }
1505 return 0;
1506}
1507
1508
1516l_ok
1517selWrite(const char *fname,
1518 SEL *sel)
1519{
1520FILE *fp;
1521
1522 PROCNAME("selWrite");
1523
1524 if (!fname)
1525 return ERROR_INT("fname not defined", procName, 1);
1526 if (!sel)
1527 return ERROR_INT("sel not defined", procName, 1);
1528
1529 if ((fp = fopenWriteStream(fname, "wb")) == NULL)
1530 return ERROR_INT("stream not opened", procName, 1);
1531 selWriteStream(fp, sel);
1532 fclose(fp);
1533
1534 return 0;
1535}
1536
1537
1545l_ok
1547 SEL *sel)
1548{
1549l_int32 sx, sy, cx, cy, i, j;
1550
1551 PROCNAME("selWriteStream");
1552
1553 if (!fp)
1554 return ERROR_INT("stream not defined", procName, 1);
1555 if (!sel)
1556 return ERROR_INT("sel not defined", procName, 1);
1557 selGetParameters(sel, &sy, &sx, &cy, &cx);
1558
1559 fprintf(fp, " Sel Version %d\n", SEL_VERSION_NUMBER);
1560 fprintf(fp, " ------ %s ------\n", selGetName(sel));
1561 fprintf(fp, " sy = %d, sx = %d, cy = %d, cx = %d\n", sy, sx, cy, cx);
1562 for (i = 0; i < sy; i++) {
1563 fprintf(fp, " ");
1564 for (j = 0; j < sx; j++)
1565 fprintf(fp, "%d", sel->data[i][j]);
1566 fprintf(fp, "\n");
1567 }
1568 fprintf(fp, "\n");
1569
1570 return 0;
1571}
1572
1573
1574/*----------------------------------------------------------------------*
1575 * Building custom hit-miss sels from compiled strings *
1576 *----------------------------------------------------------------------*/
1606SEL *
1607selCreateFromString(const char *text,
1608 l_int32 h,
1609 l_int32 w,
1610 const char *name)
1611{
1612SEL *sel;
1613l_int32 y, x, norig;
1614char ch;
1615
1616 PROCNAME("selCreateFromString");
1617
1618 if (!text || text[0] == '\0')
1619 return (SEL *)ERROR_PTR("text undefined or empty", procName, NULL);
1620 if (h < 1)
1621 return (SEL *)ERROR_PTR("height must be > 0", procName, NULL);
1622 if (w < 1)
1623 return (SEL *)ERROR_PTR("width must be > 0", procName, NULL);
1624 if (strlen(text) != (size_t)w * h)
1625 return (SEL *)ERROR_PTR("text size != w * h", procName, NULL);
1626
1627 sel = selCreate(h, w, name);
1628 norig = 0;
1629 for (y = 0; y < h; ++y) {
1630 for (x = 0; x < w; ++x) {
1631 ch = *(text++);
1632 switch (ch)
1633 {
1634 case 'X':
1635 norig++;
1636 selSetOrigin(sel, y, x);
1637 /* fall through */
1638 case 'x':
1639 selSetElement(sel, y, x, SEL_HIT);
1640 break;
1641
1642 case 'O':
1643 norig++;
1644 selSetOrigin(sel, y, x);
1645 /* fall through */
1646 case 'o':
1647 selSetElement(sel, y, x, SEL_MISS);
1648 break;
1649
1650 case 'C':
1651 norig++;
1652 selSetOrigin(sel, y, x);
1653 /* fall through */
1654 case ' ':
1655 selSetElement(sel, y, x, SEL_DONT_CARE);
1656 break;
1657
1658 case '\n':
1659 /* ignored */
1660 continue;
1661
1662 default:
1663 selDestroy(&sel);
1664 return (SEL *)ERROR_PTR("unknown char", procName, NULL);
1665 }
1666 }
1667 }
1668 if (norig != 1) {
1669 L_ERROR("Exactly one origin must be specified; this string has %d\n",
1670 procName, norig);
1671 selDestroy(&sel);
1672 }
1673
1674 return sel;
1675}
1676
1677
1697char *
1699{
1700char is_center;
1701char *str, *strptr;
1702l_int32 type;
1703l_int32 sx, sy, cx, cy, x, y;
1704
1705 PROCNAME("selPrintToString");
1706
1707 if (!sel)
1708 return (char *)ERROR_PTR("sel not defined", procName, NULL);
1709
1710 selGetParameters(sel, &sy, &sx, &cy, &cx);
1711 if ((str = (char *)LEPT_CALLOC(1, sy * (sx + 1) + 1)) == NULL)
1712 return (char *)ERROR_PTR("calloc fail for str", procName, NULL);
1713 strptr = str;
1714
1715 for (y = 0; y < sy; ++y) {
1716 for (x = 0; x < sx; ++x) {
1717 selGetElement(sel, y, x, &type);
1718 is_center = (x == cx && y == cy);
1719 switch (type) {
1720 case SEL_HIT:
1721 *(strptr++) = is_center ? 'X' : 'x';
1722 break;
1723 case SEL_MISS:
1724 *(strptr++) = is_center ? 'O' : 'o';
1725 break;
1726 case SEL_DONT_CARE:
1727 *(strptr++) = is_center ? 'C' : ' ';
1728 break;
1729 }
1730 }
1731 *(strptr++) = '\n';
1732 }
1733
1734 return str;
1735}
1736
1737
1738/*----------------------------------------------------------------------*
1739 * Building custom hit-miss sels from a simple file format *
1740 *----------------------------------------------------------------------*/
1772SELA *
1773selaCreateFromFile(const char *filename)
1774{
1775char *filestr, *line;
1776l_int32 i, n, first, last, nsel, insel;
1777size_t nbytes;
1778NUMA *nafirst, *nalast;
1779SARRAY *sa;
1780SEL *sel;
1781SELA *sela;
1782
1783 PROCNAME("selaCreateFromFile");
1784
1785 if (!filename)
1786 return (SELA *)ERROR_PTR("filename not defined", procName, NULL);
1787
1788 filestr = (char *)l_binaryRead(filename, &nbytes);
1789 sa = sarrayCreateLinesFromString(filestr, 1);
1790 LEPT_FREE(filestr);
1791 n = sarrayGetCount(sa);
1792 sela = selaCreate(0);
1793
1794 /* Find the start and end lines for each Sel.
1795 * We allow the "blank" lines to be null strings or
1796 * to have standard whitespace (' ','\t',\'n') or be '#'. */
1797 nafirst = numaCreate(0);
1798 nalast = numaCreate(0);
1799 insel = FALSE;
1800 for (i = 0; i < n; i++) {
1801 line = sarrayGetString(sa, i, L_NOCOPY);
1802 if (!insel &&
1803 (line[0] != '\0' && line[0] != ' ' &&
1804 line[0] != '\t' && line[0] != '\n' && line[0] != '#')) {
1805 numaAddNumber(nafirst, i);
1806 insel = TRUE;
1807 continue;
1808 }
1809 if (insel &&
1810 (line[0] == '\0' || line[0] == ' ' ||
1811 line[0] == '\t' || line[0] == '\n' || line[0] == '#')) {
1812 numaAddNumber(nalast, i - 1);
1813 insel = FALSE;
1814 continue;
1815 }
1816 }
1817 if (insel) /* fell off the end of the file */
1818 numaAddNumber(nalast, n - 1);
1819
1820 /* Extract sels */
1821 nsel = numaGetCount(nafirst);
1822 for (i = 0; i < nsel; i++) {
1823 numaGetIValue(nafirst, i, &first);
1824 numaGetIValue(nalast, i, &last);
1825 if ((sel = selCreateFromSArray(sa, first, last)) == NULL) {
1826 lept_stderr("Error reading sel from %d to %d\n", first, last);
1827 selaDestroy(&sela);
1828 sarrayDestroy(&sa);
1829 numaDestroy(&nafirst);
1830 numaDestroy(&nalast);
1831 return (SELA *)ERROR_PTR("bad sela file", procName, NULL);
1832 }
1833 selaAddSel(sela, sel, NULL, 0);
1834 }
1835
1836 numaDestroy(&nafirst);
1837 numaDestroy(&nalast);
1838 sarrayDestroy(&sa);
1839 return sela;
1840}
1841
1842
1873static SEL *
1875 l_int32 first,
1876 l_int32 last)
1877{
1878char ch;
1879char *name, *line;
1880l_int32 n, len, i, w, h, y, x;
1881SEL *sel;
1882
1883 PROCNAME("selCreateFromSArray");
1884
1885 if (!sa)
1886 return (SEL *)ERROR_PTR("sa not defined", procName, NULL);
1887 n = sarrayGetCount(sa);
1888 if (first < 0 || first >= n || last <= first || last >= n)
1889 return (SEL *)ERROR_PTR("invalid range", procName, NULL);
1890
1891 name = sarrayGetString(sa, first, L_NOCOPY);
1892 h = last - first;
1893 line = sarrayGetString(sa, first + 1, L_NOCOPY);
1894 len = strlen(line);
1895 if (line[0] != '"' || line[len - 1] != '"')
1896 return (SEL *)ERROR_PTR("invalid format", procName, NULL);
1897 w = len - 2;
1898 if ((sel = selCreate(h, w, name)) == NULL)
1899 return (SEL *)ERROR_PTR("sel not made", procName, NULL);
1900 for (i = first + 1; i <= last; i++) {
1901 line = sarrayGetString(sa, i, L_NOCOPY);
1902 y = i - first - 1;
1903 for (x = 0; x < w; ++x) {
1904 ch = line[x + 1]; /* skip the leading double-quote */
1905 switch (ch)
1906 {
1907 case 'X':
1908 selSetOrigin(sel, y, x); /* set origin and hit */
1909 /* fall through */
1910 case 'x':
1911 selSetElement(sel, y, x, SEL_HIT);
1912 break;
1913
1914 case 'O':
1915 selSetOrigin(sel, y, x); /* set origin and miss */
1916 /* fall through */
1917 case 'o':
1918 selSetElement(sel, y, x, SEL_MISS);
1919 break;
1920
1921 case 'C':
1922 selSetOrigin(sel, y, x); /* set origin and don't-care */
1923 /* fall through */
1924 case ' ':
1925 selSetElement(sel, y, x, SEL_DONT_CARE);
1926 break;
1927
1928 default:
1929 selDestroy(&sel);
1930 return (SEL *)ERROR_PTR("unknown char", procName, NULL);
1931 }
1932 }
1933 }
1934
1935 return sel;
1936}
1937
1938
1939/*----------------------------------------------------------------------*
1940 * Making hit-only SELs from Pta and Pix *
1941 *----------------------------------------------------------------------*/
1955SEL *
1957 l_int32 cy,
1958 l_int32 cx,
1959 const char *name)
1960{
1961l_int32 i, n, x, y, w, h;
1962BOX *box;
1963SEL *sel;
1964
1965 PROCNAME("selCreateFromPta");
1966
1967 if (!pta)
1968 return (SEL *)ERROR_PTR("pta not defined", procName, NULL);
1969 if (cy < 0 || cx < 0)
1970 return (SEL *)ERROR_PTR("(cy, cx) not both >= 0", procName, NULL);
1971 n = ptaGetCount(pta);
1972 if (n == 0)
1973 return (SEL *)ERROR_PTR("no pts in pta", procName, NULL);
1974
1975 box = ptaGetBoundingRegion(pta);
1976 boxGetGeometry(box, &x, &y, &w, &h);
1977 boxDestroy(&box);
1978 if (x < 0 || y < 0)
1979 return (SEL *)ERROR_PTR("not all x and y >= 0", procName, NULL);
1980
1981 sel = selCreate(y + h, x + w, name);
1982 selSetOrigin(sel, cy, cx);
1983 for (i = 0; i < n; i++) {
1984 ptaGetIPt(pta, i, &x, &y);
1985 selSetElement(sel, y, x, SEL_HIT);
1986 }
1987
1988 return sel;
1989}
1990
1991
2007SEL *
2009 l_int32 cy,
2010 l_int32 cx,
2011 const char *name)
2012{
2013SEL *sel;
2014l_int32 i, j, w, h, d, nhits;
2015l_uint32 val;
2016
2017 PROCNAME("selCreateFromPix");
2018
2019 if (!pix)
2020 return (SEL *)ERROR_PTR("pix not defined", procName, NULL);
2021 if (cy < 0 || cx < 0)
2022 return (SEL *)ERROR_PTR("(cy, cx) not both >= 0", procName, NULL);
2023 pixGetDimensions(pix, &w, &h, &d);
2024 if (d != 1)
2025 return (SEL *)ERROR_PTR("pix not 1 bpp", procName, NULL);
2026 if (w > MaxPixTemplateSize || h > MaxPixTemplateSize) {
2027 L_ERROR("pix template too large (w = %d, h = %d)\n", procName, w, h);
2028 return NULL;
2029 }
2030 pixCountPixels(pix, &nhits, NULL);
2031 if (nhits > MaxPixTemplateHits) {
2032 L_ERROR("too many hits (%d) in pix template\n", procName, nhits);
2033 return NULL;
2034 }
2035
2036 sel = selCreate(h, w, name);
2037 selSetOrigin(sel, cy, cx);
2038 for (i = 0; i < h; i++) {
2039 for (j = 0; j < w; j++) {
2040 pixGetPixel(pix, j, i, &val);
2041 if (val)
2042 selSetElement(sel, i, j, SEL_HIT);
2043 }
2044 }
2045
2046 return sel;
2047}
2048
2049
2050/*----------------------------------------------------------------------*
2051 * Making hit-miss sels from color Pix and image files *
2052 *----------------------------------------------------------------------*/
2067SEL *
2068selReadFromColorImage(const char *pathname)
2069{
2070PIX *pix;
2071SEL *sel;
2072char *basename, *selname;
2073
2074 PROCNAME("selReadFromColorImage");
2075
2076 splitPathAtExtension (pathname, &basename, NULL);
2077 splitPathAtDirectory (basename, NULL, &selname);
2078 LEPT_FREE(basename);
2079
2080 if ((pix = pixRead(pathname)) == NULL) {
2081 LEPT_FREE(selname);
2082 return (SEL *)ERROR_PTR("pix not returned", procName, NULL);
2083 }
2084 if ((sel = selCreateFromColorPix(pix, selname)) == NULL)
2085 L_ERROR("sel not made\n", procName);
2086
2087 LEPT_FREE(selname);
2088 pixDestroy(&pix);
2089 return sel;
2090}
2091
2092
2116SEL *
2118 const char *selname)
2119{
2120PIXCMAP *cmap;
2121SEL *sel;
2122l_int32 hascolor, num_origins, nohits;
2123l_int32 w, h, d, i, j, red, green, blue;
2124l_uint32 pixval;
2125
2126 PROCNAME("selCreateFromColorPix");
2127
2128 if (!pixs)
2129 return (SEL *)ERROR_PTR("pixs not defined", procName, NULL);
2130
2131 hascolor = FALSE;
2132 cmap = pixGetColormap(pixs);
2133 if (cmap)
2134 pixcmapHasColor(cmap, &hascolor);
2135 pixGetDimensions(pixs, &w, &h, &d);
2136 if (hascolor == FALSE && d != 32)
2137 return (SEL *)ERROR_PTR("pixs has no color", procName, NULL);
2138
2139 if ((sel = selCreate (h, w, NULL)) == NULL)
2140 return (SEL *)ERROR_PTR ("sel not made", procName, NULL);
2141 selSetOrigin (sel, h / 2, w / 2); /* default */
2142 selSetName(sel, selname);
2143
2144 num_origins = 0;
2145 nohits = TRUE;
2146 for (i = 0; i < h; i++) {
2147 for (j = 0; j < w; j++) {
2148 pixGetPixel (pixs, j, i, &pixval);
2149
2150 if (cmap) {
2151 pixcmapGetColor (cmap, pixval, &red, &green, &blue);
2152 } else {
2153 red = GET_DATA_BYTE (&pixval, COLOR_RED);
2154 green = GET_DATA_BYTE (&pixval, COLOR_GREEN);
2155 blue = GET_DATA_BYTE (&pixval, COLOR_BLUE);
2156 }
2157
2158 if (red < 255 && green < 255 && blue < 255) {
2159 num_origins++;
2160 if (num_origins == 1) /* first one found */
2161 selSetOrigin (sel, i, j);
2162 if (num_origins == 2)
2163 L_WARNING("multiple origins in sel image\n", procName);
2164 }
2165 if (!red && green && !blue) {
2166 nohits = FALSE;
2167 selSetElement (sel, i, j, SEL_HIT);
2168 } else if (red && !green && !blue) {
2169 selSetElement (sel, i, j, SEL_MISS);
2170 } else if (red && green && blue) {
2171 selSetElement (sel, i, j, SEL_DONT_CARE);
2172 } else {
2173 selDestroy(&sel);
2174 return (SEL *)ERROR_PTR("invalid color", procName, NULL);
2175 }
2176 }
2177 }
2178
2179 if (nohits) {
2180 selDestroy(&sel);
2181 return (SEL *)ERROR_PTR("no hits in sel", procName, NULL);
2182 }
2183 return sel;
2184}
2185
2186
2202SELA *
2204 SARRAY *sa)
2205{
2206char *str;
2207l_int32 i, n;
2208PIX *pix;
2209SEL *sel;
2210SELA *sela;
2211
2212 PROCNAME("selaCreateFromColorPixa");
2213
2214 if (!pixa)
2215 return (SELA *)ERROR_PTR("pixa not defined", procName, NULL);
2216 if (!sa)
2217 return (SELA *)ERROR_PTR("sa of sel names not defined", procName, NULL);
2218
2219 n = pixaGetCount(pixa);
2220 if ((sela = selaCreate(n)) == NULL)
2221 return (SELA *)ERROR_PTR("sela not allocated", procName, NULL);
2222 for (i = 0; i < n; i++) {
2223 pix = pixaGetPix(pixa, i, L_CLONE);
2224 str = sarrayGetString(sa, i, L_NOCOPY);
2225 sel = selCreateFromColorPix(pix, str);
2226 selaAddSel(sela, sel, NULL, L_INSERT);
2227 pixDestroy(&pix);
2228 }
2229 return sela;
2230}
2231
2232
2233/*----------------------------------------------------------------------*
2234 * Printable display of sel *
2235 *----------------------------------------------------------------------*/
2254PIX *
2256 l_int32 size,
2257 l_int32 gthick)
2258{
2259l_int32 i, j, w, h, sx, sy, cx, cy, type, width;
2260l_int32 radius1, radius2, shift1, shift2, x0, y0;
2261PIX *pixd, *pix2, *pixh, *pixm, *pixorig;
2262PTA *pta1, *pta2, *pta1t, *pta2t;
2263
2264 PROCNAME("selDisplayInPix");
2265
2266 if (!sel)
2267 return (PIX *)ERROR_PTR("sel not defined", procName, NULL);
2268 if (size < 13) {
2269 L_WARNING("size < 13; setting to 13\n", procName);
2270 size = 13;
2271 }
2272 if (size % 2 == 0)
2273 size++;
2274 if (gthick < 2) {
2275 L_WARNING("grid thickness < 2; setting to 2\n", procName);
2276 gthick = 2;
2277 }
2278 selGetParameters(sel, &sy, &sx, &cy, &cx);
2279 w = size * sx + gthick * (sx + 1);
2280 h = size * sy + gthick * (sy + 1);
2281 pixd = pixCreate(w, h, 1);
2282
2283 /* Generate grid lines */
2284 for (i = 0; i <= sy; i++)
2285 pixRenderLine(pixd, 0, gthick / 2 + i * (size + gthick),
2286 w - 1, gthick / 2 + i * (size + gthick),
2287 gthick, L_SET_PIXELS);
2288 for (j = 0; j <= sx; j++)
2289 pixRenderLine(pixd, gthick / 2 + j * (size + gthick), 0,
2290 gthick / 2 + j * (size + gthick), h - 1,
2291 gthick, L_SET_PIXELS);
2292
2293 /* Generate hit and miss patterns */
2294 radius1 = (l_int32)(0.85 * ((size - 1) / 2.0) + 0.5); /* of hit */
2295 radius2 = (l_int32)(0.65 * ((size - 1) / 2.0) + 0.5); /* of inner miss */
2296 pta1 = generatePtaFilledCircle(radius1);
2297 pta2 = generatePtaFilledCircle(radius2);
2298 shift1 = (size - 1) / 2 - radius1; /* center circle in square */
2299 shift2 = (size - 1) / 2 - radius2;
2300 pta1t = ptaTransform(pta1, shift1, shift1, 1.0, 1.0);
2301 pta2t = ptaTransform(pta2, shift2, shift2, 1.0, 1.0);
2302 pixh = pixGenerateFromPta(pta1t, size, size); /* hits */
2303 pix2 = pixGenerateFromPta(pta2t, size, size);
2304 pixm = pixSubtract(NULL, pixh, pix2);
2305
2306 /* Generate crossed lines for origin pattern */
2307 pixorig = pixCreate(size, size, 1);
2308 width = size / 8;
2309 pixRenderLine(pixorig, size / 2, (l_int32)(0.12 * size),
2310 size / 2, (l_int32)(0.88 * size),
2311 width, L_SET_PIXELS);
2312 pixRenderLine(pixorig, (l_int32)(0.15 * size), size / 2,
2313 (l_int32)(0.85 * size), size / 2,
2314 width, L_FLIP_PIXELS);
2315 pixRasterop(pixorig, size / 2 - width, size / 2 - width,
2316 2 * width, 2 * width, PIX_NOT(PIX_DST), NULL, 0, 0);
2317
2318 /* Specialize origin pattern for this sel */
2319 selGetTypeAtOrigin(sel, &type);
2320 if (type == SEL_HIT)
2321 pixXor(pixorig, pixorig, pixh);
2322 else if (type == SEL_MISS)
2323 pixXor(pixorig, pixorig, pixm);
2324
2325 /* Paste the patterns in */
2326 y0 = gthick;
2327 for (i = 0; i < sy; i++) {
2328 x0 = gthick;
2329 for (j = 0; j < sx; j++) {
2330 selGetElement(sel, i, j, &type);
2331 if (i == cy && j == cx) /* origin */
2332 pixRasterop(pixd, x0, y0, size, size, PIX_SRC, pixorig, 0, 0);
2333 else if (type == SEL_HIT)
2334 pixRasterop(pixd, x0, y0, size, size, PIX_SRC, pixh, 0, 0);
2335 else if (type == SEL_MISS)
2336 pixRasterop(pixd, x0, y0, size, size, PIX_SRC, pixm, 0, 0);
2337 x0 += size + gthick;
2338 }
2339 y0 += size + gthick;
2340 }
2341
2342 pixDestroy(&pix2);
2343 pixDestroy(&pixh);
2344 pixDestroy(&pixm);
2345 pixDestroy(&pixorig);
2346 ptaDestroy(&pta1);
2347 ptaDestroy(&pta1t);
2348 ptaDestroy(&pta2);
2349 ptaDestroy(&pta2t);
2350 return pixd;
2351}
2352
2353
2372PIX *
2374 l_int32 size,
2375 l_int32 gthick,
2376 l_int32 spacing,
2377 l_int32 ncols)
2378{
2379l_int32 nsels, i, w, width;
2380PIX *pixt, *pixd;
2381PIXA *pixa;
2382SEL *sel;
2383
2384 PROCNAME("selaDisplayInPix");
2385
2386 if (!sela)
2387 return (PIX *)ERROR_PTR("sela not defined", procName, NULL);
2388 if (size < 13) {
2389 L_WARNING("size < 13; setting to 13\n", procName);
2390 size = 13;
2391 }
2392 if (size % 2 == 0)
2393 size++;
2394 if (gthick < 2) {
2395 L_WARNING("grid thickness < 2; setting to 2\n", procName);
2396 gthick = 2;
2397 }
2398 if (spacing < 5) {
2399 L_WARNING("spacing < 5; setting to 5\n", procName);
2400 spacing = 5;
2401 }
2402
2403 /* Accumulate the pix of each sel */
2404 nsels = selaGetCount(sela);
2405 pixa = pixaCreate(nsels);
2406 for (i = 0; i < nsels; i++) {
2407 sel = selaGetSel(sela, i);
2408 pixt = selDisplayInPix(sel, size, gthick);
2409 pixaAddPix(pixa, pixt, L_INSERT);
2410 }
2411
2412 /* Find the tiled output width, using just the first
2413 * ncols pix in the pixa. If all pix have the same width,
2414 * they will align properly in columns. */
2415 width = 0;
2416 ncols = L_MIN(nsels, ncols);
2417 for (i = 0; i < ncols; i++) {
2418 pixt = pixaGetPix(pixa, i, L_CLONE);
2419 pixGetDimensions(pixt, &w, NULL, NULL);
2420 width += w;
2421 pixDestroy(&pixt);
2422 }
2423 width += (ncols + 1) * spacing; /* add spacing all around as well */
2424
2425 pixd = pixaDisplayTiledInRows(pixa, 1, width, 1.0, 0, spacing, 0);
2426 pixaDestroy(&pixa);
2427 return pixd;
2428}
#define GET_DATA_BYTE(pdata, n)
Definition: arrayaccess.h:188
void boxDestroy(BOX **pbox)
boxDestroy()
Definition: boxbasic.c:282
l_ok boxGetGeometry(BOX *box, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxGetGeometry()
Definition: boxbasic.c:313
l_ok pixcmapHasColor(PIXCMAP *cmap, l_int32 *pcolor)
pixcmapHasColor()
Definition: colormap.c:1075
l_ok pixcmapGetColor(PIXCMAP *cmap, l_int32 index, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
pixcmapGetColor()
Definition: colormap.c:824
l_ok pixRenderLine(PIX *pix, l_int32 x1, l_int32 y1, l_int32 x2, l_int32 y2, l_int32 width, l_int32 op)
pixRenderLine()
Definition: graphics.c:1496
PTA * generatePtaFilledCircle(l_int32 radius)
generatePtaFilledCircle()
Definition: graphics.c:833
l_ok selectComposableSizes(l_int32 size, l_int32 *pfactor1, l_int32 *pfactor2)
selectComposableSizes()
Definition: morph.c:1132
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:478
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 * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:194
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:621
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1113
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:315
l_ok pixGetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 *pval)
pixGetPixel()
Definition: pix2.c:190
l_ok pixCountPixels(PIX *pixs, l_int32 *pcount, l_int32 *tab8)
pixCountPixels()
Definition: pix3.c:1937
PIX * pixSubtract(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixSubtract()
Definition: pix3.c:1753
PIX * pixXor(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixXor()
Definition: pix3.c:1688
#define PIX_DST
Definition: pix.h:331
@ COLOR_BLUE
Definition: pix.h:206
@ COLOR_RED
Definition: pix.h:204
@ COLOR_GREEN
Definition: pix.h:205
@ L_FLIP_PIXELS
Definition: pix.h:774
@ L_SET_PIXELS
Definition: pix.h:772
@ L_COPY
Definition: pix.h:712
@ L_CLONE
Definition: pix.h:713
@ L_NOCOPY
Definition: pix.h:710
@ L_INSERT
Definition: pix.h:711
#define PIX_SRC
Definition: pix.h:330
#define PIX_NOT(op)
Definition: pix.h:332
l_ok pixaAddPix(PIXA *pixa, PIX *pix, l_int32 copyflag)
pixaAddPix()
Definition: pixabasic.c:506
void pixaDestroy(PIXA **ppixa)
pixaDestroy()
Definition: pixabasic.c:412
PIXA * pixaCreate(l_int32 n)
pixaCreate()
Definition: pixabasic.c:167
l_int32 pixaGetCount(PIXA *pixa)
pixaGetCount()
Definition: pixabasic.c:650
PIX * pixaGetPix(PIXA *pixa, l_int32 index, l_int32 accesstype)
pixaGetPix()
Definition: pixabasic.c:691
PIX * pixaDisplayTiledInRows(PIXA *pixa, l_int32 outdepth, l_int32 maxwidth, l_float32 scalefactor, l_int32 background, l_int32 spacing, l_int32 border)
pixaDisplayTiledInRows()
Definition: pixafunc2.c:746
l_ok ptaGetIPt(PTA *pta, l_int32 index, l_int32 *px, l_int32 *py)
ptaGetIPt()
Definition: ptabasic.c:578
l_int32 ptaGetCount(PTA *pta)
ptaGetCount()
Definition: ptabasic.c:527
void ptaDestroy(PTA **ppta)
ptaDestroy()
Definition: ptabasic.c:195
PIX * pixGenerateFromPta(PTA *pta, l_int32 w, l_int32 h)
pixGenerateFromPta()
Definition: ptafunc1.c:2023
BOX * ptaGetBoundingRegion(PTA *pta)
ptaGetBoundingRegion()
Definition: ptafunc1.c:444
PTA * ptaTransform(PTA *ptas, l_int32 shiftx, l_int32 shifty, l_float32 scalex, l_float32 scaley)
ptaTransform()
Definition: ptafunc1.c:740
PIX * pixRead(const char *filename)
pixRead()
Definition: readfile.c:193
l_ok pixRasterop(PIX *pixd, l_int32 dx, l_int32 dy, l_int32 dw, l_int32 dh, l_int32 op, PIX *pixs, l_int32 sx, l_int32 sy)
pixRasterop()
Definition: rop.c:204
SARRAY * sarrayCreate(l_int32 n)
sarrayCreate()
Definition: sarray1.c:170
char * sarrayToString(SARRAY *sa, l_int32 addnlflag)
sarrayToString()
Definition: sarray1.c:785
char * sarrayGetString(SARRAY *sa, l_int32 index, l_int32 copyflag)
sarrayGetString()
Definition: sarray1.c:703
l_int32 sarrayGetCount(SARRAY *sa)
sarrayGetCount()
Definition: sarray1.c:643
void sarrayDestroy(SARRAY **psa)
sarrayDestroy()
Definition: sarray1.c:362
SARRAY * sarrayCreateLinesFromString(const char *string, l_int32 blankflag)
sarrayCreateLinesFromString()
Definition: sarray1.c:283
l_ok sarrayAddString(SARRAY *sa, const char *string, l_int32 copyflag)
sarrayAddString()
Definition: sarray1.c:451
PIX * selDisplayInPix(SEL *sel, l_int32 size, l_int32 gthick)
selDisplayInPix()
Definition: sel1.c:2255
static SEL * selCreateFromSArray(SARRAY *sa, l_int32 first, l_int32 last)
selCreateFromSArray()
Definition: sel1.c:1874
SELA * selaCreateFromFile(const char *filename)
selaCreateFromFile()
Definition: sel1.c:1773
l_ok selWrite(const char *fname, SEL *sel)
selWrite()
Definition: sel1.c:1517
SEL * selReadStream(FILE *fp)
selReadStream()
Definition: sel1.c:1406
l_ok selWriteStream(FILE *fp, SEL *sel)
selWriteStream()
Definition: sel1.c:1546
static const l_int32 InitialPtrArraySize
Definition: sel1.c:151
l_ok selGetParameters(SEL *sel, l_int32 *psy, l_int32 *psx, l_int32 *pcy, l_int32 *pcx)
selGetParameters()
Definition: sel1.c:848
l_ok getCompositeParameters(l_int32 size, l_int32 *psize1, l_int32 *psize2, char **pnameh1, char **pnameh2, char **pnamev1, char **pnamev2)
getCompositeParameters()
Definition: sel1.c:1101
l_ok selFindMaxTranslations(SEL *sel, l_int32 *pxp, l_int32 *pyp, l_int32 *pxn, l_int32 *pyn)
selFindMaxTranslations()
Definition: sel1.c:1190
l_ok selSetName(SEL *sel, const char *name)
selSetName()
Definition: sel1.c:708
l_ok selaWriteStream(FILE *fp, SELA *sela)
selaWriteStream()
Definition: sel1.c:1484
SEL * selCreate(l_int32 height, l_int32 width, const char *name)
selCreate()
Definition: sel1.c:310
SELA * selaReadStream(FILE *fp)
selaReadStream()
Definition: sel1.c:1336
void selaDestroy(SELA **psela)
selaDestroy()
Definition: sel1.c:276
SEL * selCreateFromPix(PIX *pix, l_int32 cy, l_int32 cx, const char *name)
selCreateFromPix()
Definition: sel1.c:2008
l_ok selaFindSelByName(SELA *sela, const char *name, l_int32 *pindex, SEL **psel)
selaFindSelByName()
Definition: sel1.c:730
SEL * selRotateOrth(SEL *sel, l_int32 quads)
selRotateOrth()
Definition: sel1.c:1240
l_ok selSetOrigin(SEL *sel, l_int32 cy, l_int32 cx)
selSetOrigin()
Definition: sel1.c:878
SEL * selaGetSel(SELA *sela, l_int32 i)
selaGetSel()
Definition: sel1.c:662
void selDestroy(SEL **psel)
selDestroy()
Definition: sel1.c:340
l_ok selaAddSel(SELA *sela, SEL *sel, const char *selname, l_int32 copyflag)
selaAddSel()
Definition: sel1.c:559
char * selaGetCombName(SELA *sela, l_int32 size, l_int32 direction)
selaGetCombName()
Definition: sel1.c:974
l_ok selSetElement(SEL *sel, l_int32 row, l_int32 col, l_int32 type)
selSetElement()
Definition: sel1.c:819
SELA * selaRead(const char *fname)
selaRead()
Definition: sel1.c:1307
char * selPrintToString(SEL *sel)
selPrintToString()
Definition: sel1.c:1698
SELA * selaCreate(l_int32 n)
selaCreate()
Definition: sel1.c:251
l_int32 ** create2dIntArray(l_int32 sy, l_int32 sx)
create2dIntArray()
Definition: sel1.c:517
SEL * selRead(const char *fname)
selRead()
Definition: sel1.c:1377
l_ok selaWrite(const char *fname, SELA *sela)
selaWrite()
Definition: sel1.c:1455
SEL * selCreateFromString(const char *text, l_int32 h, l_int32 w, const char *name)
selCreateFromString()
Definition: sel1.c:1607
SEL * selCopy(SEL *sel)
selCopy()
Definition: sel1.c:371
SARRAY * selaGetSelnames(SELA *sela)
selaGetSelnames()
Definition: sel1.c:1145
SELA * selaCreateFromColorPixa(PIXA *pixa, SARRAY *sa)
Definition: sel1.c:2203
static l_int32 selaExtendArray(SELA *sela)
selaExtendArray()
Definition: sel1.c:609
l_ok selGetElement(SEL *sel, l_int32 row, l_int32 col, l_int32 *ptype)
selGetElement()
Definition: sel1.c:779
l_int32 selaGetCount(SELA *sela)
selaGetCount()
Definition: sel1.c:637
SEL * selCreateFromPta(PTA *pta, l_int32 cy, l_int32 cx, const char *name)
selCreateFromPta()
Definition: sel1.c:1956
SEL * selReadFromColorImage(const char *pathname)
Definition: sel1.c:2068
char * selaGetBrickName(SELA *sela, l_int32 hsize, l_int32 vsize)
selaGetBrickName()
Definition: sel1.c:935
SEL * selCreateComb(l_int32 factor1, l_int32 factor2, l_int32 direction)
selCreateComb()
Definition: sel1.c:462
l_ok selGetTypeAtOrigin(SEL *sel, l_int32 *ptype)
selGetTypeAtOrigin()
Definition: sel1.c:900
char * selGetName(SEL *sel)
selGetName()
Definition: sel1.c:683
SEL * selCreateBrick(l_int32 h, l_int32 w, l_int32 cy, l_int32 cx, l_int32 type)
selCreateBrick()
Definition: sel1.c:418
SEL * selCreateFromColorPix(PIX *pixs, const char *selname)
Definition: sel1.c:2117
PIX * selaDisplayInPix(SELA *sela, l_int32 size, l_int32 gthick, l_int32 spacing, l_int32 ncols)
selaDisplayInPix()
Definition: sel1.c:2373
SELA * selaAddBasic(SELA *sela)
selaAddBasic()
Definition: sel2.c:99
SELA * selaAddDwaCombs(SELA *sela)
selaAddDwaCombs()
Definition: sel2.c:368
Definition: pix.h:481
Definition: array.h:71
Definition: pix.h:139
Definition: pix.h:456
Definition: pix.h:517
Definition: array.h:127
l_int32 sx
Definition: morph.h:64
l_int32 cy
Definition: morph.h:65
l_int32 cx
Definition: morph.h:66
l_int32 ** data
Definition: morph.h:67
char * name
Definition: morph.h:68
l_int32 sy
Definition: morph.h:63
Definition: morph.h:74
struct Sel ** sel
Definition: morph.h:77
l_int32 nalloc
Definition: morph.h:76
l_int32 n
Definition: morph.h:75
void lept_stderr(const char *fmt,...)
lept_stderr()
Definition: utils1.c:306
l_ok stringReplace(char **pdest, const char *src)
stringReplace()
Definition: utils2.c:345
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1975
l_ok splitPathAtExtension(const char *pathname, char **pbasename, char **pextension)
splitPathAtExtension()
Definition: utils2.c:2894
l_ok splitPathAtDirectory(const char *pathname, char **pdir, char **ptail)
splitPathAtDirectory()
Definition: utils2.c:2824
l_uint8 * l_binaryRead(const char *filename, size_t *pnbytes)
l_binaryRead()
Definition: utils2.c:1352
FILE * fopenReadStream(const char *filename)
fopenReadStream()
Definition: utils2.c:1932
void * reallocNew(void **pindata, size_t oldsize, size_t newsize)
reallocNew()
Definition: utils2.c:1302
l_ok l_binaryWrite(const char *filename, const char *operation, const void *data, size_t nbytes)
l_binaryWrite()
Definition: utils2.c:1569
char * stringNew(const char *src)
stringNew()
Definition: utils2.c:223