Leptonica 1.82.0
Image processing and image analysis suite
boxfunc3.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
63#ifdef HAVE_CONFIG_H
64#include <config_auto.h>
65#endif /* HAVE_CONFIG_H */
66
67#include "allheaders.h"
68
69static l_int32 pixSearchForRectangle(PIX *pixs, BOX *boxs, l_int32 minsum,
70 l_int32 skipdist, l_int32 delta,
71 l_int32 maxbg, l_int32 sideflag,
72 BOXA *boxat, NUMA *nascore);
73
74#ifndef NO_CONSOLE_IO
75#define DEBUG_SPLIT 0
76#endif /* ~NO_CONSOLE_IO */
77
78/*---------------------------------------------------------------------*
79 * Boxa/Boxaa painting into Pix *
80 *---------------------------------------------------------------------*/
96PIX *
98 l_int32 connectivity,
99 BOXA **pboxa)
100{
101BOXA *boxa;
102PIX *pixd;
103
104 PROCNAME("pixMaskConnComp");
105
106 if (pboxa) *pboxa = NULL;
107 if (!pixs || pixGetDepth(pixs) != 1)
108 return (PIX *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
109 if (connectivity != 4 && connectivity != 8)
110 return (PIX *)ERROR_PTR("connectivity not 4 or 8", procName, NULL);
111
112 boxa = pixConnComp(pixs, NULL, connectivity);
113 pixd = pixCreateTemplate(pixs);
114 if (boxaGetCount(boxa) != 0)
115 pixMaskBoxa(pixd, pixd, boxa, L_SET_PIXELS);
116 if (pboxa)
117 *pboxa = boxa;
118 else
119 boxaDestroy(&boxa);
120 return pixd;
121}
122
123
150PIX *
152 PIX *pixs,
153 BOXA *boxa,
154 l_int32 op)
155{
156l_int32 i, n, x, y, w, h;
157BOX *box;
158
159 PROCNAME("pixMaskBoxa");
160
161 if (!pixs)
162 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
163 if (pixGetColormap(pixs))
164 return (PIX *)ERROR_PTR("pixs is cmapped", procName, NULL);
165 if (pixd && (pixd != pixs))
166 return (PIX *)ERROR_PTR("if pixd, must be in-place", procName, NULL);
167 if (!boxa)
168 return (PIX *)ERROR_PTR("boxa not defined", procName, NULL);
169 if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
170 return (PIX *)ERROR_PTR("invalid op", procName, NULL);
171
172 pixd = pixCopy(pixd, pixs);
173 if ((n = boxaGetCount(boxa)) == 0) {
174 L_WARNING("no boxes to mask\n", procName);
175 return pixd;
176 }
177
178 for (i = 0; i < n; i++) {
179 box = boxaGetBox(boxa, i, L_CLONE);
180 boxGetGeometry(box, &x, &y, &w, &h);
181 if (op == L_SET_PIXELS)
182 pixRasterop(pixd, x, y, w, h, PIX_SET, NULL, 0, 0);
183 else if (op == L_CLEAR_PIXELS)
184 pixRasterop(pixd, x, y, w, h, PIX_CLR, NULL, 0, 0);
185 else /* op == L_FLIP_PIXELS */
186 pixRasterop(pixd, x, y, w, h, PIX_NOT(PIX_DST), NULL, 0, 0);
187 boxDestroy(&box);
188 }
189
190 return pixd;
191}
192
193
219PIX *
221 BOXA *boxa,
222 l_uint32 val)
223{
224l_int32 i, n, d, rval, gval, bval, newindex;
225l_int32 mapvacancy; /* true only if cmap and not full */
226BOX *box;
227PIX *pixd;
228PIXCMAP *cmap;
229
230 PROCNAME("pixPaintBoxa");
231
232 if (!pixs)
233 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
234 if (!boxa)
235 return (PIX *)ERROR_PTR("boxa not defined", procName, NULL);
236
237 if ((n = boxaGetCount(boxa)) == 0) {
238 L_WARNING("no boxes to paint; returning a copy\n", procName);
239 return pixCopy(NULL, pixs);
240 }
241
242 mapvacancy = FALSE;
243 if ((cmap = pixGetColormap(pixs)) != NULL) {
244 if (pixcmapGetCount(cmap) < 256)
245 mapvacancy = TRUE;
246 }
247 if (pixGetDepth(pixs) == 1 || mapvacancy)
248 pixd = pixConvertTo8(pixs, TRUE);
249 else
250 pixd = pixConvertTo32(pixs);
251 if (!pixd)
252 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
253
254 d = pixGetDepth(pixd);
255 if (d == 8) { /* colormapped */
256 cmap = pixGetColormap(pixd);
257 extractRGBValues(val, &rval, &gval, &bval);
258 if (pixcmapAddNewColor(cmap, rval, gval, bval, &newindex)) {
259 pixDestroy(&pixd);
260 return (PIX *)ERROR_PTR("cmap full; can't add", procName, NULL);
261 }
262 }
263
264 for (i = 0; i < n; i++) {
265 box = boxaGetBox(boxa, i, L_CLONE);
266 if (d == 8)
267 pixSetInRectArbitrary(pixd, box, newindex);
268 else
269 pixSetInRectArbitrary(pixd, box, val);
270 boxDestroy(&box);
271 }
272
273 return pixd;
274}
275
276
285PIX *
287 BOXA *boxa,
288 l_int32 op)
289{
290l_int32 i, n, d, index;
291l_uint32 color;
292BOX *box;
293PIX *pixd;
294PIXCMAP *cmap;
295
296 PROCNAME("pixSetBlackOrWhiteBoxa");
297
298 if (!pixs)
299 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
300 if (!boxa)
301 return pixCopy(NULL, pixs);
302 if ((n = boxaGetCount(boxa)) == 0)
303 return pixCopy(NULL, pixs);
304
305 pixd = pixCopy(NULL, pixs);
306 d = pixGetDepth(pixd);
307 if (d == 1) {
308 for (i = 0; i < n; i++) {
309 box = boxaGetBox(boxa, i, L_CLONE);
310 if (op == L_SET_WHITE)
311 pixClearInRect(pixd, box);
312 else
313 pixSetInRect(pixd, box);
314 boxDestroy(&box);
315 }
316 return pixd;
317 }
318
319 cmap = pixGetColormap(pixs);
320 if (cmap) {
321 color = (op == L_SET_WHITE) ? 1 : 0;
322 pixcmapAddBlackOrWhite(cmap, color, &index);
323 } else if (d == 8) {
324 color = (op == L_SET_WHITE) ? 0xff : 0x0;
325 } else if (d == 32) {
326 color = (op == L_SET_WHITE) ? 0xffffff00 : 0x0;
327 } else if (d == 2) {
328 color = (op == L_SET_WHITE) ? 0x3 : 0x0;
329 } else if (d == 4) {
330 color = (op == L_SET_WHITE) ? 0xf : 0x0;
331 } else if (d == 16) {
332 color = (op == L_SET_WHITE) ? 0xffff : 0x0;
333 } else {
334 pixDestroy(&pixd);
335 return (PIX *)ERROR_PTR("invalid depth", procName, NULL);
336 }
337
338 for (i = 0; i < n; i++) {
339 box = boxaGetBox(boxa, i, L_CLONE);
340 if (cmap)
341 pixSetInRectArbitrary(pixd, box, index);
342 else
343 pixSetInRectArbitrary(pixd, box, color);
344 boxDestroy(&box);
345 }
346
347 return pixd;
348}
349
350
366PIX *
368 BOXA *boxa)
369{
370l_int32 i, n, d, rval, gval, bval, index;
371l_uint32 val;
372BOX *box;
373PIX *pixd;
374PIXCMAP *cmap;
375
376 PROCNAME("pixPaintBoxaRandom");
377
378 if (!pixs)
379 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
380 if (!boxa)
381 return (PIX *)ERROR_PTR("boxa not defined", procName, NULL);
382
383 if ((n = boxaGetCount(boxa)) == 0) {
384 L_WARNING("no boxes to paint; returning a copy\n", procName);
385 return pixCopy(NULL, pixs);
386 }
387
388 if (pixGetDepth(pixs) == 1)
389 pixd = pixConvert1To8(NULL, pixs, 255, 0);
390 else
391 pixd = pixConvertTo32(pixs);
392 if (!pixd)
393 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
394
395 cmap = pixcmapCreateRandom(8, 1, 1);
396 d = pixGetDepth(pixd); /* either 8 or 32 */
397 if (d == 8) /* colormapped */
398 pixSetColormap(pixd, cmap);
399
400 for (i = 0; i < n; i++) {
401 box = boxaGetBox(boxa, i, L_CLONE);
402 index = 1 + (i % 254);
403 if (d == 8) {
404 pixSetInRectArbitrary(pixd, box, index);
405 } else { /* d == 32 */
406 pixcmapGetColor(cmap, index, &rval, &gval, &bval);
407 composeRGBPixel(rval, gval, bval, &val);
408 pixSetInRectArbitrary(pixd, box, val);
409 }
410 boxDestroy(&box);
411 }
412
413 if (d == 32)
414 pixcmapDestroy(&cmap);
415 return pixd;
416}
417
418
437PIX *
439 BOXA *boxa,
440 l_float32 fract)
441{
442l_int32 i, n, rval, gval, bval, index;
443l_uint32 val;
444BOX *box;
445PIX *pixd;
446PIXCMAP *cmap;
447
448 PROCNAME("pixBlendBoxaRandom");
449
450 if (!pixs)
451 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
452 if (!boxa)
453 return (PIX *)ERROR_PTR("boxa not defined", procName, NULL);
454 if (fract < 0.0 || fract > 1.0) {
455 L_WARNING("fract must be in [0.0, 1.0]; setting to 0.5\n", procName);
456 fract = 0.5;
457 }
458
459 if ((n = boxaGetCount(boxa)) == 0) {
460 L_WARNING("no boxes to paint; returning a copy\n", procName);
461 return pixCopy(NULL, pixs);
462 }
463
464 if ((pixd = pixConvertTo32(pixs)) == NULL)
465 return (PIX *)ERROR_PTR("pixd not defined", procName, NULL);
466
467 cmap = pixcmapCreateRandom(8, 1, 1);
468 for (i = 0; i < n; i++) {
469 box = boxaGetBox(boxa, i, L_CLONE);
470 index = 1 + (i % 254);
471 pixcmapGetColor(cmap, index, &rval, &gval, &bval);
472 composeRGBPixel(rval, gval, bval, &val);
473 pixBlendInRect(pixd, box, val, fract);
474 boxDestroy(&box);
475 }
476
477 pixcmapDestroy(&cmap);
478 return pixd;
479}
480
481
498PIX *
500 BOXA *boxa,
501 l_int32 width,
502 l_uint32 val)
503{
504l_int32 rval, gval, bval, newindex;
505l_int32 mapvacancy; /* true only if cmap and not full */
506PIX *pixd;
507PIXCMAP *cmap;
508
509 PROCNAME("pixDrawBoxa");
510
511 if (!pixs)
512 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
513 if (!boxa)
514 return (PIX *)ERROR_PTR("boxa not defined", procName, NULL);
515 if (width < 1)
516 return (PIX *)ERROR_PTR("width must be >= 1", procName, NULL);
517
518 if (boxaGetCount(boxa) == 0) {
519 L_WARNING("no boxes to draw; returning a copy\n", procName);
520 return pixCopy(NULL, pixs);
521 }
522
523 mapvacancy = FALSE;
524 if ((cmap = pixGetColormap(pixs)) != NULL) {
525 if (pixcmapGetCount(cmap) < 256)
526 mapvacancy = TRUE;
527 }
528 if (pixGetDepth(pixs) == 1 || mapvacancy)
529 pixd = pixConvertTo8(pixs, TRUE);
530 else
531 pixd = pixConvertTo32(pixs);
532 if (!pixd)
533 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
534
535 extractRGBValues(val, &rval, &gval, &bval);
536 if (pixGetDepth(pixd) == 8) { /* colormapped */
537 cmap = pixGetColormap(pixd);
538 pixcmapAddNewColor(cmap, rval, gval, bval, &newindex);
539 }
540
541 pixRenderBoxaArb(pixd, boxa, width, rval, gval, bval);
542 return pixd;
543}
544
545
562PIX *
564 BOXA *boxa,
565 l_int32 width)
566{
567l_int32 i, n, rval, gval, bval, index;
568BOX *box;
569PIX *pixd;
570PIXCMAP *cmap;
571PTAA *ptaa;
572
573 PROCNAME("pixDrawBoxaRandom");
574
575 if (!pixs)
576 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
577 if (!boxa)
578 return (PIX *)ERROR_PTR("boxa not defined", procName, NULL);
579 if (width < 1)
580 return (PIX *)ERROR_PTR("width must be >= 1", procName, NULL);
581
582 if ((n = boxaGetCount(boxa)) == 0) {
583 L_WARNING("no boxes to draw; returning a copy\n", procName);
584 return pixCopy(NULL, pixs);
585 }
586
587 /* Input depth = 1 bpp; generate cmapped output */
588 if (pixGetDepth(pixs) == 1) {
589 ptaa = generatePtaaBoxa(boxa);
590 pixd = pixRenderRandomCmapPtaa(pixs, ptaa, 1, width, 1);
591 ptaaDestroy(&ptaa);
592 return pixd;
593 }
594
595 /* Generate rgb output */
596 pixd = pixConvertTo32(pixs);
597 cmap = pixcmapCreateRandom(8, 1, 1);
598 for (i = 0; i < n; i++) {
599 box = boxaGetBox(boxa, i, L_CLONE);
600 index = 1 + (i % 254);
601 pixcmapGetColor(cmap, index, &rval, &gval, &bval);
602 pixRenderBoxArb(pixd, box, width, rval, gval, bval);
603 boxDestroy(&box);
604 }
605 pixcmapDestroy(&cmap);
606 return pixd;
607}
608
609
636PIX *
638 BOXAA *baa,
639 l_int32 linewba,
640 l_int32 linewb,
641 l_uint32 colorba,
642 l_uint32 colorb,
643 l_int32 w,
644 l_int32 h)
645{
646l_int32 i, j, n, m, rbox, gbox, bbox, rboxa, gboxa, bboxa;
647BOX *box;
648BOXA *boxa;
649PIX *pixd;
650PIXCMAP *cmap;
651
652 PROCNAME("boxaaDisplay");
653
654 if (!baa)
655 return (PIX *)ERROR_PTR("baa not defined", procName, NULL);
656
657 if (w <= 0 || h <= 0) {
658 if (pixs)
659 pixGetDimensions(pixs, &w, &h, NULL);
660 else
661 boxaaGetExtent(baa, &w, &h, NULL, NULL);
662 }
663
664 if (pixs) {
665 pixd = pixConvertTo8(pixs, 1);
666 cmap = pixGetColormap(pixd);
667 } else {
668 pixd = pixCreate(w, h, 8);
669 cmap = pixcmapCreate(8);
670 pixSetColormap(pixd, cmap);
671 pixcmapAddColor(cmap, 255, 255, 255);
672 }
673 extractRGBValues(colorb, &rbox, &gbox, &bbox);
674 extractRGBValues(colorba, &rboxa, &gboxa, &bboxa);
675 pixcmapAddColor(cmap, rbox, gbox, bbox);
676 pixcmapAddColor(cmap, rboxa, gboxa, bboxa);
677
678 n = boxaaGetCount(baa);
679 for (i = 0; i < n; i++) {
680 boxa = boxaaGetBoxa(baa, i, L_CLONE);
681 boxaGetExtent(boxa, NULL, NULL, &box);
682 pixRenderBoxArb(pixd, box, linewba, rboxa, gboxa, bboxa);
683 boxDestroy(&box);
684 m = boxaGetCount(boxa);
685 for (j = 0; j < m; j++) {
686 box = boxaGetBox(boxa, j, L_CLONE);
687 pixRenderBoxArb(pixd, box, linewb, rbox, gbox, bbox);
688 boxDestroy(&box);
689 }
690 boxaDestroy(&boxa);
691 }
692
693 return pixd;
694}
695
696
718PIXA *
720 BOXAA *baa,
721 l_int32 colorflag,
722 l_int32 width)
723{
724l_int32 i, j, nba, n, nbox, rval, gval, bval;
725l_uint32 color;
726l_uint32 colors[255];
727BOXA *boxa;
728BOX *box;
729PIX *pix;
730PIXA *pixad;
731
732 PROCNAME("pixaDisplayBoxaa");
733
734 if (!pixas)
735 return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
736 if (!baa)
737 return (PIXA *)ERROR_PTR("baa not defined", procName, NULL);
738 if (width < 1)
739 return (PIXA *)ERROR_PTR("width must be >= 1", procName, NULL);
740 if ((nba = boxaaGetCount(baa)) < 1)
741 return (PIXA *)ERROR_PTR("no boxa in baa", procName, NULL);
742 if ((n = pixaGetCount(pixas)) == 0)
743 return (PIXA *)ERROR_PTR("no pix in pixas", procName, NULL);
744 if (n != nba)
745 return (PIXA *)ERROR_PTR("num pix != num boxa", procName, NULL);
746 if (colorflag == L_DRAW_RED)
747 color = 0xff000000;
748 else if (colorflag == L_DRAW_GREEN)
749 color = 0x00ff0000;
750 else if (colorflag == L_DRAW_BLUE)
751 color = 0x0000ff00;
752 else if (colorflag == L_DRAW_RGB)
753 color = 0x000000ff;
754 else if (colorflag == L_DRAW_RANDOM)
755 color = 0x00000000;
756 else
757 return (PIXA *)ERROR_PTR("invalid colorflag", procName, NULL);
758
759 if (colorflag == L_DRAW_RED || colorflag == L_DRAW_GREEN ||
760 colorflag == L_DRAW_BLUE) {
761 for (i = 0; i < 255; i++)
762 colors[i] = color;
763 } else if (colorflag == L_DRAW_RGB) {
764 for (i = 0; i < 255; i++) {
765 if (i % 3 == L_DRAW_RED)
766 colors[i] = 0xff000000;
767 else if (i % 3 == L_DRAW_GREEN)
768 colors[i] = 0x00ff0000;
769 else /* i % 3 == L_DRAW_BLUE) */
770 colors[i] = 0x0000ff00;
771 }
772 } else if (colorflag == L_DRAW_RANDOM) {
773 for (i = 0; i < 255; i++) {
774 rval = (l_uint32)rand() & 0xff;
775 gval = (l_uint32)rand() & 0xff;
776 bval = (l_uint32)rand() & 0xff;
777 composeRGBPixel(rval, gval, bval, &colors[i]);
778 }
779 }
780
781 pixad = pixaCreate(n);
782 for (i = 0; i < n; i++) {
783 pix = pixaGetPix(pixas, i, L_COPY);
784 boxa = boxaaGetBoxa(baa, i, L_CLONE);
785 nbox = boxaGetCount(boxa);
786 for (j = 0; j < nbox; j++) {
787 box = boxaGetBox(boxa, j, L_CLONE);
788 extractRGBValues(colors[j % 255], &rval, &gval, &bval);
789 pixRenderBoxArb(pix, box, width, rval, gval, bval);
790 boxDestroy(&box);
791 }
792 boxaDestroy(&boxa);
793 pixaAddPix(pixad, pix, L_INSERT);
794 }
795
796 return pixad;
797}
798
799
800/*---------------------------------------------------------------------*
801 * Split mask components into Boxa *
802 *---------------------------------------------------------------------*/
837BOXA *
839 l_int32 minsum,
840 l_int32 skipdist,
841 l_int32 delta,
842 l_int32 maxbg,
843 l_int32 maxcomps,
844 l_int32 remainder)
845{
846l_int32 i, n;
847BOX *box;
848BOXA *boxa, *boxas, *boxad;
849PIX *pix;
850PIXA *pixas;
851
852 PROCNAME("pixSplitIntoBoxa");
853
854 if (!pixs || pixGetDepth(pixs) != 1)
855 return (BOXA *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
856
857 boxas = pixConnComp(pixs, &pixas, 8);
858 n = boxaGetCount(boxas);
859 boxad = boxaCreate(0);
860 for (i = 0; i < n; i++) {
861 pix = pixaGetPix(pixas, i, L_CLONE);
862 box = boxaGetBox(boxas, i, L_CLONE);
863 boxa = pixSplitComponentIntoBoxa(pix, box, minsum, skipdist,
864 delta, maxbg, maxcomps, remainder);
865 boxaJoin(boxad, boxa, 0, -1);
866 pixDestroy(&pix);
867 boxDestroy(&box);
868 boxaDestroy(&boxa);
869 }
870
871 pixaDestroy(&pixas);
872 boxaDestroy(&boxas);
873 return boxad;
874}
875
876
946BOXA *
948 BOX *box,
949 l_int32 minsum,
950 l_int32 skipdist,
951 l_int32 delta,
952 l_int32 maxbg,
953 l_int32 maxcomps,
954 l_int32 remainder)
955{
956l_int32 i, w, h, boxx, boxy, bx, by, bw, bh, maxdir, maxscore;
957l_int32 iter;
958BOX *boxs; /* shrinks as rectangular regions are removed */
959BOX *boxt1, *boxt2, *boxt3;
960BOXA *boxat; /* stores rectangle data for each side in an iteration */
961BOXA *boxad;
962NUMA *nascore, *nas;
963PIX *pixs;
964
965 PROCNAME("pixSplitComponentIntoBoxa");
966
967 if (!pix || pixGetDepth(pix) != 1)
968 return (BOXA *)ERROR_PTR("pix undefined or not 1 bpp", procName, NULL);
969
970 pixs = pixCopy(NULL, pix);
971 pixGetDimensions(pixs, &w, &h, NULL);
972 if (box)
973 boxGetGeometry(box, &boxx, &boxy, NULL, NULL);
974 else
975 boxx = boxy = 0;
976 boxs = boxCreate(0, 0, w, h);
977 boxad = boxaCreate(0);
978
979 iter = 0;
980 while (boxs != NULL) {
981 boxGetGeometry(boxs, &bx, &by, &bw, &bh);
982 boxat = boxaCreate(4); /* potential rectangular regions */
983 nascore = numaCreate(4);
984 for (i = 0; i < 4; i++) {
985 pixSearchForRectangle(pixs, boxs, minsum, skipdist, delta, maxbg,
986 i, boxat, nascore);
987 }
988 nas = numaGetSortIndex(nascore, L_SORT_DECREASING);
989 numaGetIValue(nas, 0, &maxdir);
990 numaGetIValue(nascore, maxdir, &maxscore);
991#if DEBUG_SPLIT
992 lept_stderr("Iteration: %d\n", iter);
993 boxPrintStreamInfo(stderr, boxs);
994 boxaWriteStderr(boxat);
995 lept_stderr("\nmaxdir = %d, maxscore = %d\n\n", maxdir, maxscore);
996#endif /* DEBUG_SPLIT */
997 if (maxscore > 0) { /* accept this */
998 boxt1 = boxaGetBox(boxat, maxdir, L_CLONE);
999 boxt2 = boxTransform(boxt1, boxx, boxy, 1.0, 1.0);
1000 boxaAddBox(boxad, boxt2, L_INSERT);
1001 pixClearInRect(pixs, boxt1);
1002 boxDestroy(&boxt1);
1003 pixClipBoxToForeground(pixs, boxs, NULL, &boxt3);
1004 boxDestroy(&boxs);
1005 boxs = boxt3;
1006 if (boxs) {
1007 boxGetGeometry(boxs, NULL, NULL, &bw, &bh);
1008 if (bw < 2 || bh < 2)
1009 boxDestroy(&boxs); /* we're done */
1010 }
1011 } else { /* no more valid rectangles can be found */
1012 if (remainder == 1) { /* save the last box */
1013 boxt1 = boxTransform(boxs, boxx, boxy, 1.0, 1.0);
1014 boxaAddBox(boxad, boxt1, L_INSERT);
1015 }
1016 boxDestroy(&boxs); /* we're done */
1017 }
1018 boxaDestroy(&boxat);
1019 numaDestroy(&nascore);
1020 numaDestroy(&nas);
1021
1022 iter++;
1023 if ((iter == maxcomps) && boxs) {
1024 if (remainder == 1) { /* save the last box */
1025 boxt1 = boxTransform(boxs, boxx, boxy, 1.0, 1.0);
1026 boxaAddBox(boxad, boxt1, L_INSERT);
1027 }
1028 boxDestroy(&boxs); /* we're done */
1029 }
1030 }
1031
1032 pixDestroy(&pixs);
1033 return boxad;
1034}
1035
1036
1061static l_int32
1063 BOX *boxs,
1064 l_int32 minsum,
1065 l_int32 skipdist,
1066 l_int32 delta,
1067 l_int32 maxbg,
1068 l_int32 sideflag,
1069 BOXA *boxat,
1070 NUMA *nascore)
1071{
1072l_int32 bx, by, bw, bh, width, height, setref, atref;
1073l_int32 minincol, maxincol, mininrow, maxinrow, minval, maxval, bgref;
1074l_int32 x, y, x0, y0, xref, yref, colsum, rowsum, score, countref, diff;
1075void **lines1;
1076BOX *boxr;
1077
1078 PROCNAME("pixSearchForRectangle");
1079
1080 if (!pixs || pixGetDepth(pixs) != 1)
1081 return ERROR_INT("pixs undefined or not 1 bpp", procName, 1);
1082 if (!boxs)
1083 return ERROR_INT("boxs not defined", procName, 1);
1084 if (!boxat)
1085 return ERROR_INT("boxat not defined", procName, 1);
1086 if (!nascore)
1087 return ERROR_INT("nascore not defined", procName, 1);
1088
1089 lines1 = pixGetLinePtrs(pixs, NULL);
1090 boxGetGeometry(boxs, &bx, &by, &bw, &bh);
1091 boxr = NULL;
1092 setref = 0;
1093 atref = 0;
1094 maxval = 0;
1095 minval = 100000;
1096 score = 0; /* sum of all (fg - bg) pixels seen in the scan */
1097 xref = yref = 100000; /* init to impossibly big number */
1098 if (sideflag == L_FROM_LEFT) {
1099 for (x = bx; x < bx + bw; x++) {
1100 colsum = 0;
1101 maxincol = 0;
1102 minincol = 100000;
1103 for (y = by; y < by + bh; y++) {
1104 if (GET_DATA_BIT(lines1[y], x)) {
1105 colsum++;
1106 if (y > maxincol) maxincol = y;
1107 if (y < minincol) minincol = y;
1108 }
1109 }
1110 score += colsum;
1111
1112 /* Enough fg to sweep out a rectangle? */
1113 if (!setref && colsum >= minsum) {
1114 setref = 1;
1115 xref = x + 10;
1116 if (xref >= bx + bw)
1117 goto failure;
1118 }
1119
1120 /* Reached the reference line; save the count;
1121 * if there is too much bg, the rectangle is invalid. */
1122 if (setref && x == xref) {
1123 atref = 1;
1124 countref = colsum;
1125 bgref = maxincol - minincol + 1 - countref;
1126 if (bgref > maxbg)
1127 goto failure;
1128 }
1129
1130 /* Have we left the rectangle? If so, save it along
1131 * with the score. */
1132 if (atref) {
1133 diff = L_ABS(colsum - countref);
1134 if (diff >= delta || x == bx + bw - 1) {
1135 height = maxval - minval + 1;
1136 width = x - bx;
1137 if (x == bx + bw - 1) width = x - bx + 1;
1138 boxr = boxCreate(bx, minval, width, height);
1139 score = 2 * score - width * height;
1140 goto success;
1141 }
1142 }
1143 maxval = L_MAX(maxval, maxincol);
1144 minval = L_MIN(minval, minincol);
1145 }
1146 goto failure;
1147 } else if (sideflag == L_FROM_RIGHT) {
1148 for (x = bx + bw - 1; x >= bx; x--) {
1149 colsum = 0;
1150 maxincol = 0;
1151 minincol = 100000;
1152 for (y = by; y < by + bh; y++) {
1153 if (GET_DATA_BIT(lines1[y], x)) {
1154 colsum++;
1155 if (y > maxincol) maxincol = y;
1156 if (y < minincol) minincol = y;
1157 }
1158 }
1159 score += colsum;
1160 if (!setref && colsum >= minsum) {
1161 setref = 1;
1162 xref = x - 10;
1163 if (xref < bx)
1164 goto failure;
1165 }
1166 if (setref && x == xref) {
1167 atref = 1;
1168 countref = colsum;
1169 bgref = maxincol - minincol + 1 - countref;
1170 if (bgref > maxbg)
1171 goto failure;
1172 }
1173 if (atref) {
1174 diff = L_ABS(colsum - countref);
1175 if (diff >= delta || x == bx) {
1176 height = maxval - minval + 1;
1177 x0 = x + 1;
1178 if (x == bx) x0 = x;
1179 width = bx + bw - x0;
1180 boxr = boxCreate(x0, minval, width, height);
1181 score = 2 * score - width * height;
1182 goto success;
1183 }
1184 }
1185 maxval = L_MAX(maxval, maxincol);
1186 minval = L_MIN(minval, minincol);
1187 }
1188 goto failure;
1189 } else if (sideflag == L_FROM_TOP) {
1190 for (y = by; y < by + bh; y++) {
1191 rowsum = 0;
1192 maxinrow = 0;
1193 mininrow = 100000;
1194 for (x = bx; x < bx + bw; x++) {
1195 if (GET_DATA_BIT(lines1[y], x)) {
1196 rowsum++;
1197 if (x > maxinrow) maxinrow = x;
1198 if (x < mininrow) mininrow = x;
1199 }
1200 }
1201 score += rowsum;
1202 if (!setref && rowsum >= minsum) {
1203 setref = 1;
1204 yref = y + 10;
1205 if (yref >= by + bh)
1206 goto failure;
1207 }
1208 if (setref && y == yref) {
1209 atref = 1;
1210 countref = rowsum;
1211 bgref = maxinrow - mininrow + 1 - countref;
1212 if (bgref > maxbg)
1213 goto failure;
1214 }
1215 if (atref) {
1216 diff = L_ABS(rowsum - countref);
1217 if (diff >= delta || y == by + bh - 1) {
1218 width = maxval - minval + 1;
1219 height = y - by;
1220 if (y == by + bh - 1) height = y - by + 1;
1221 boxr = boxCreate(minval, by, width, height);
1222 score = 2 * score - width * height;
1223 goto success;
1224 }
1225 }
1226 maxval = L_MAX(maxval, maxinrow);
1227 minval = L_MIN(minval, mininrow);
1228 }
1229 goto failure;
1230 } else if (sideflag == L_FROM_BOT) {
1231 for (y = by + bh - 1; y >= by; y--) {
1232 rowsum = 0;
1233 maxinrow = 0;
1234 mininrow = 100000;
1235 for (x = bx; x < bx + bw; x++) {
1236 if (GET_DATA_BIT(lines1[y], x)) {
1237 rowsum++;
1238 if (x > maxinrow) maxinrow = x;
1239 if (x < mininrow) mininrow = x;
1240 }
1241 }
1242 score += rowsum;
1243 if (!setref && rowsum >= minsum) {
1244 setref = 1;
1245 yref = y - 10;
1246 if (yref < by)
1247 goto failure;
1248 }
1249 if (setref && y == yref) {
1250 atref = 1;
1251 countref = rowsum;
1252 bgref = maxinrow - mininrow + 1 - countref;
1253 if (bgref > maxbg)
1254 goto failure;
1255 }
1256 if (atref) {
1257 diff = L_ABS(rowsum - countref);
1258 if (diff >= delta || y == by) {
1259 width = maxval - minval + 1;
1260 y0 = y + 1;
1261 if (y == by) y0 = y;
1262 height = by + bh - y0;
1263 boxr = boxCreate(minval, y0, width, height);
1264 score = 2 * score - width * height;
1265 goto success;
1266 }
1267 }
1268 maxval = L_MAX(maxval, maxinrow);
1269 minval = L_MIN(minval, mininrow);
1270 }
1271 goto failure;
1272 }
1273
1274failure:
1275 numaAddNumber(nascore, 0);
1276 boxaAddBox(boxat, boxCreate(0, 0, 1, 1), L_INSERT); /* min box */
1277 LEPT_FREE(lines1);
1278 return 0;
1279
1280success:
1281 numaAddNumber(nascore, score);
1282 boxaAddBox(boxat, boxr, L_INSERT);
1283 LEPT_FREE(lines1);
1284 return 0;
1285}
1286
1287
1288/*---------------------------------------------------------------------*
1289 * Represent horizontal or vertical mosaic strips *
1290 *---------------------------------------------------------------------*/
1310BOXA *
1312 l_int32 h,
1313 l_int32 direction,
1314 l_int32 size)
1315{
1316l_int32 i, nstrips, extra;
1317BOX *box;
1318BOXA *boxa;
1319
1320 PROCNAME("makeMosaicStrips");
1321
1322 if (w < 1 || h < 1)
1323 return (BOXA *)ERROR_PTR("invalid w or h", procName, NULL);
1324 if (direction != L_SCAN_HORIZONTAL && direction != L_SCAN_VERTICAL)
1325 return (BOXA *)ERROR_PTR("invalid direction", procName, NULL);
1326 if (size < 1)
1327 return (BOXA *)ERROR_PTR("size < 1", procName, NULL);
1328
1329 boxa = boxaCreate(0);
1330 if (direction == L_SCAN_HORIZONTAL) {
1331 nstrips = w / size;
1332 for (i = 0; i < nstrips; i++) {
1333 box = boxCreate(i * size, 0, size, h);
1334 boxaAddBox(boxa, box, L_INSERT);
1335 }
1336 if ((extra = w % size) > 0) {
1337 box = boxCreate(nstrips * size, 0, extra, h);
1338 boxaAddBox(boxa, box, L_INSERT);
1339 }
1340 } else {
1341 nstrips = h / size;
1342 for (i = 0; i < nstrips; i++) {
1343 box = boxCreate(0, i * size, w, size);
1344 boxaAddBox(boxa, box, L_INSERT);
1345 }
1346 if ((extra = h % size) > 0) {
1347 box = boxCreate(0, nstrips * size, w, extra);
1348 boxaAddBox(boxa, box, L_INSERT);
1349 }
1350 }
1351 return boxa;
1352}
1353
1354
1355/*---------------------------------------------------------------------*
1356 * Comparison between boxa *
1357 *---------------------------------------------------------------------*/
1389l_ok
1391 BOXA *boxa2,
1392 l_int32 areathresh,
1393 l_int32 *pnsame,
1394 l_float32 *pdiffarea,
1395 l_float32 *pdiffxor,
1396 PIX **ppixdb)
1397{
1398l_int32 w, h, x3, y3, w3, h3, x4, y4, w4, h4, n3, n4, area1, area2;
1399l_int32 count3, count4, countxor;
1400l_int32 *tab;
1401BOX *box3, *box4;
1402BOXA *boxa3, *boxa4, *boxa3t, *boxa4t;
1403PIX *pix1, *pix2, *pix3, *pix4, *pix5;
1404PIXA *pixa;
1405
1406 PROCNAME("boxaCompareRegions");
1407
1408 if (pdiffxor) *pdiffxor = 1.0;
1409 if (ppixdb) *ppixdb = NULL;
1410 if (pnsame) *pnsame = FALSE;
1411 if (pdiffarea) *pdiffarea = 1.0;
1412 if (!boxa1 || !boxa2)
1413 return ERROR_INT("boxa1 and boxa2 not both defined", procName, 1);
1414 if (!pnsame)
1415 return ERROR_INT("&nsame not defined", procName, 1);
1416 if (!pdiffarea)
1417 return ERROR_INT("&diffarea not defined", procName, 1);
1418
1419 boxa3 = boxaSelectByArea(boxa1, areathresh, L_SELECT_IF_GTE, NULL);
1420 boxa4 = boxaSelectByArea(boxa2, areathresh, L_SELECT_IF_GTE, NULL);
1421 n3 = boxaGetCount(boxa3);
1422 n4 = boxaGetCount(boxa4);
1423 if (n3 == n4)
1424 *pnsame = TRUE;
1425
1426 /* There are no boxes in one or both */
1427 if (n3 == 0 || n4 == 0) {
1428 boxaDestroy(&boxa3);
1429 boxaDestroy(&boxa4);
1430 if (n3 == 0 && n4 == 0) { /* they are both empty: we say they are the
1431 * same; otherwise, they differ maximally
1432 * and retain the default value. */
1433 *pdiffarea = 0.0;
1434 if (pdiffxor) *pdiffxor = 0.0;
1435 }
1436 return 0;
1437 }
1438
1439 /* There are boxes in both */
1440 boxaGetArea(boxa3, &area1);
1441 boxaGetArea(boxa4, &area2);
1442 *pdiffarea = (l_float32)L_ABS(area1 - area2) / (l_float32)(area1 + area2);
1443 if (!pdiffxor) {
1444 boxaDestroy(&boxa3);
1445 boxaDestroy(&boxa4);
1446 return 0;
1447 }
1448
1449 /* The easiest way to get the xor of aligned boxes is to work
1450 * with images of each boxa. This is done by translating each
1451 * boxa so that the UL corner of the region that includes all
1452 * boxes in the boxa is placed at the origin of each pix. */
1453 boxaGetExtent(boxa3, &w, &h, &box3);
1454 boxaGetExtent(boxa4, &w, &h, &box4);
1455 boxGetGeometry(box3, &x3, &y3, &w3, &h3);
1456 boxGetGeometry(box4, &x4, &y4, &w4, &h4);
1457 boxa3t = boxaTransform(boxa3, -x3, -y3, 1.0, 1.0);
1458 boxa4t = boxaTransform(boxa4, -x4, -y4, 1.0, 1.0);
1459 w = L_MAX(x3 + w3, x4 + w4);
1460 h = L_MAX(y3 + h3, y4 + h4);
1461 pix3 = pixCreate(w, h, 1); /* use the max to keep everything in the xor */
1462 pix4 = pixCreate(w, h, 1);
1463 pixMaskBoxa(pix3, pix3, boxa3t, L_SET_PIXELS);
1464 pixMaskBoxa(pix4, pix4, boxa4t, L_SET_PIXELS);
1465 tab = makePixelSumTab8();
1466 pixCountPixels(pix3, &count3, tab);
1467 pixCountPixels(pix4, &count4, tab);
1468 pix5 = pixXor(NULL, pix3, pix4);
1469 pixCountPixels(pix5, &countxor, tab);
1470 LEPT_FREE(tab);
1471 *pdiffxor = (l_float32)countxor / (l_float32)(count3 + count4);
1472
1473 if (ppixdb) {
1474 pixa = pixaCreate(2);
1475 pix1 = pixCreate(w, h, 32);
1476 pixSetAll(pix1);
1477 pixRenderHashBoxaBlend(pix1, boxa3, 5, 1, L_POS_SLOPE_LINE, 2,
1478 255, 0, 0, 0.5);
1479 pixRenderHashBoxaBlend(pix1, boxa4, 5, 1, L_NEG_SLOPE_LINE, 2,
1480 0, 255, 0, 0.5);
1481 pixaAddPix(pixa, pix1, L_INSERT);
1482 pix2 = pixCreate(w, h, 32);
1483 pixPaintThroughMask(pix2, pix3, x3, y3, 0xff000000);
1484 pixPaintThroughMask(pix2, pix4, x4, y4, 0x00ff0000);
1485 pixAnd(pix3, pix3, pix4);
1486 pixPaintThroughMask(pix2, pix3, x3, y3, 0x0000ff00);
1487 pixaAddPix(pixa, pix2, L_INSERT);
1488 *ppixdb = pixaDisplayTiledInRows(pixa, 32, 1000, 1.0, 0, 30, 2);
1489 pixaDestroy(&pixa);
1490 }
1491
1492 boxDestroy(&box3);
1493 boxDestroy(&box4);
1494 boxaDestroy(&boxa3);
1495 boxaDestroy(&boxa3t);
1496 boxaDestroy(&boxa4);
1497 boxaDestroy(&boxa4t);
1498 pixDestroy(&pix3);
1499 pixDestroy(&pix4);
1500 pixDestroy(&pix5);
1501 return 0;
1502}
1503
1504
1505/*---------------------------------------------------------------------*
1506 * Reliable selection of a single large box *
1507 *---------------------------------------------------------------------*/
1533BOX *
1535 l_float32 areaslop,
1536 l_int32 yslop,
1537 l_int32 connectivity)
1538{
1539BOX *box;
1540BOXA *boxa1;
1541
1542 PROCNAME("pixSelectLargeULComp");
1543
1544 if (!pixs)
1545 return (BOX *)ERROR_PTR("pixs not defined", procName, NULL);
1546 if (areaslop < 0.0 || areaslop > 1.0)
1547 return (BOX *)ERROR_PTR("invalid value for areaslop", procName, NULL);
1548 yslop = L_MAX(0, yslop);
1549
1550 boxa1 = pixConnCompBB(pixs, connectivity);
1551 if (boxaGetCount(boxa1) == 0) {
1552 boxaDestroy(&boxa1);
1553 return NULL;
1554 }
1555 box = boxaSelectLargeULBox(boxa1, areaslop, yslop);
1556 boxaDestroy(&boxa1);
1557 return box;
1558}
1559
1560
1574BOX *
1576 l_float32 areaslop,
1577 l_int32 yslop)
1578{
1579l_int32 w, h, i, n, x1, y1, x2, y2, select;
1580l_float32 area, max_area;
1581BOX *box;
1582BOXA *boxa1, *boxa2, *boxa3;
1583
1584 PROCNAME("boxaSelectLargeULBox");
1585
1586 if (!boxas)
1587 return (BOX *)ERROR_PTR("boxas not defined", procName, NULL);
1588 if (boxaGetCount(boxas) == 0)
1589 return (BOX *)ERROR_PTR("no boxes in boxas", procName, NULL);
1590 if (areaslop < 0.0 || areaslop > 1.0)
1591 return (BOX *)ERROR_PTR("invalid value for areaslop", procName, NULL);
1592 yslop = L_MAX(0, yslop);
1593
1594 boxa1 = boxaSort(boxas, L_SORT_BY_AREA, L_SORT_DECREASING, NULL);
1595 boxa2 = boxaSort(boxa1, L_SORT_BY_Y, L_SORT_INCREASING, NULL);
1596 n = boxaGetCount(boxa2);
1597 boxaGetBoxGeometry(boxa1, 0, NULL, NULL, &w, &h); /* biggest box by area */
1598 max_area = (l_float32)(w * h);
1599
1600 /* boxa3 collects all boxes eligible by area, sorted top-down */
1601 boxa3 = boxaCreate(4);
1602 for (i = 0; i < n; i++) {
1603 boxaGetBoxGeometry(boxa2, i, NULL, NULL, &w, &h);
1604 area = (l_float32)(w * h);
1605 if (area / max_area >= areaslop) {
1606 box = boxaGetBox(boxa2, i, L_COPY);
1607 boxaAddBox(boxa3, box, L_INSERT);
1608 }
1609 }
1610
1611 /* Take the first (top-most box) unless the second (etc) has
1612 * nearly the same y value but a smaller x value. */
1613 n = boxaGetCount(boxa3);
1614 boxaGetBoxGeometry(boxa3, 0, &x1, &y1, NULL, NULL);
1615 select = 0;
1616 for (i = 1; i < n; i++) {
1617 boxaGetBoxGeometry(boxa3, i, &x2, &y2, NULL, NULL);
1618 if (y2 - y1 < yslop && x2 < x1) {
1619 select = i;
1620 x1 = x2; /* but always compare against y1 */
1621 }
1622 }
1623
1624 box = boxaGetBox(boxa3, select, L_COPY);
1625 boxaDestroy(&boxa1);
1626 boxaDestroy(&boxa2);
1627 boxaDestroy(&boxa3);
1628 return box;
1629}
#define GET_DATA_BIT(pdata, n)
Definition: arrayaccess.h:123
BOXA * boxaaGetBoxa(BOXAA *baa, l_int32 index, l_int32 accessflag)
boxaaGetBoxa()
Definition: boxbasic.c:1501
BOX * boxaGetBox(BOXA *boxa, l_int32 index, l_int32 accessflag)
boxaGetBox()
Definition: boxbasic.c:779
void boxDestroy(BOX **pbox)
boxDestroy()
Definition: boxbasic.c:282
BOX * boxCreate(l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxCreate()
Definition: boxbasic.c:172
l_int32 boxaaGetCount(BOXAA *baa)
boxaaGetCount()
Definition: boxbasic.c:1454
l_ok boxaGetBoxGeometry(BOXA *boxa, l_int32 index, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxaGetBoxGeometry()
Definition: boxbasic.c:879
l_int32 boxaGetCount(BOXA *boxa)
boxaGetCount()
Definition: boxbasic.c:734
l_ok boxaWriteStderr(BOXA *boxa)
boxaWriteStderr()
Definition: boxbasic.c:2333
l_ok boxGetGeometry(BOX *box, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxGetGeometry()
Definition: boxbasic.c:313
BOXA * boxaCreate(l_int32 n)
boxaCreate()
Definition: boxbasic.c:502
l_ok boxaAddBox(BOXA *boxa, BOX *box, l_int32 copyflag)
boxaAddBox()
Definition: boxbasic.c:620
void boxaDestroy(BOXA **pboxa)
boxaDestroy()
Definition: boxbasic.c:583
l_ok boxPrintStreamInfo(FILE *fp, BOX *box)
boxPrintStreamInfo()
Definition: boxbasic.c:2431
l_ok boxaJoin(BOXA *boxad, BOXA *boxas, l_int32 istart, l_int32 iend)
boxaJoin()
Definition: boxfunc1.c:2537
l_ok boxaaGetExtent(BOXAA *baa, l_int32 *pw, l_int32 *ph, BOX **pbox, BOXA **pboxa)
boxaaGetExtent()
Definition: boxfunc2.c:1566
BOX * boxTransform(BOX *box, l_int32 shiftx, l_int32 shifty, l_float32 scalex, l_float32 scaley)
boxTransform()
Definition: boxfunc2.c:152
BOXA * boxaTransform(BOXA *boxas, l_int32 shiftx, l_int32 shifty, l_float32 scalex, l_float32 scaley)
boxaTransform()
Definition: boxfunc2.c:102
BOXA * boxaSort(BOXA *boxas, l_int32 sorttype, l_int32 sortorder, NUMA **pnaindex)
boxaSort()
Definition: boxfunc2.c:637
PIX * pixBlendBoxaRandom(PIX *pixs, BOXA *boxa, l_float32 fract)
pixBlendBoxaRandom()
Definition: boxfunc3.c:438
BOX * pixSelectLargeULComp(PIX *pixs, l_float32 areaslop, l_int32 yslop, l_int32 connectivity)
pixSelectLargeULComp()
Definition: boxfunc3.c:1534
PIX * pixPaintBoxaRandom(PIX *pixs, BOXA *boxa)
pixPaintBoxaRandom()
Definition: boxfunc3.c:367
PIX * pixPaintBoxa(PIX *pixs, BOXA *boxa, l_uint32 val)
pixPaintBoxa()
Definition: boxfunc3.c:220
BOXA * pixSplitComponentIntoBoxa(PIX *pix, BOX *box, l_int32 minsum, l_int32 skipdist, l_int32 delta, l_int32 maxbg, l_int32 maxcomps, l_int32 remainder)
pixSplitComponentIntoBoxa()
Definition: boxfunc3.c:947
PIX * pixDrawBoxaRandom(PIX *pixs, BOXA *boxa, l_int32 width)
pixDrawBoxaRandom()
Definition: boxfunc3.c:563
BOXA * makeMosaicStrips(l_int32 w, l_int32 h, l_int32 direction, l_int32 size)
makeMosaicStrips()
Definition: boxfunc3.c:1311
PIXA * pixaDisplayBoxaa(PIXA *pixas, BOXAA *baa, l_int32 colorflag, l_int32 width)
pixaDisplayBoxaa()
Definition: boxfunc3.c:719
PIX * pixMaskConnComp(PIX *pixs, l_int32 connectivity, BOXA **pboxa)
pixMaskConnComp()
Definition: boxfunc3.c:97
PIX * boxaaDisplay(PIX *pixs, BOXAA *baa, l_int32 linewba, l_int32 linewb, l_uint32 colorba, l_uint32 colorb, l_int32 w, l_int32 h)
boxaaDisplay()
Definition: boxfunc3.c:637
PIX * pixDrawBoxa(PIX *pixs, BOXA *boxa, l_int32 width, l_uint32 val)
pixDrawBoxa()
Definition: boxfunc3.c:499
l_ok boxaCompareRegions(BOXA *boxa1, BOXA *boxa2, l_int32 areathresh, l_int32 *pnsame, l_float32 *pdiffarea, l_float32 *pdiffxor, PIX **ppixdb)
boxaCompareRegions()
Definition: boxfunc3.c:1390
PIX * pixMaskBoxa(PIX *pixd, PIX *pixs, BOXA *boxa, l_int32 op)
pixMaskBoxa()
Definition: boxfunc3.c:151
PIX * pixSetBlackOrWhiteBoxa(PIX *pixs, BOXA *boxa, l_int32 op)
pixSetBlackOrWhiteBoxa()
Definition: boxfunc3.c:286
BOX * boxaSelectLargeULBox(BOXA *boxas, l_float32 areaslop, l_int32 yslop)
boxaSelectLargeULBox()
Definition: boxfunc3.c:1575
BOXA * pixSplitIntoBoxa(PIX *pixs, l_int32 minsum, l_int32 skipdist, l_int32 delta, l_int32 maxbg, l_int32 maxcomps, l_int32 remainder)
pixSplitIntoBoxa()
Definition: boxfunc3.c:838
static l_int32 pixSearchForRectangle(PIX *pixs, BOX *boxs, l_int32 minsum, l_int32 skipdist, l_int32 delta, l_int32 maxbg, l_int32 sideflag, BOXA *boxat, NUMA *nascore)
pixSearchForRectangle()
Definition: boxfunc3.c:1062
l_ok boxaGetArea(BOXA *boxa, l_int32 *parea)
boxaGetArea()
Definition: boxfunc4.c:1287
l_ok boxaGetExtent(BOXA *boxa, l_int32 *pw, l_int32 *ph, BOX **pbox)
boxaGetExtent()
Definition: boxfunc4.c:953
BOXA * boxaSelectByArea(BOXA *boxas, l_int32 area, l_int32 relation, l_int32 *pchanged)
boxaSelectByArea()
Definition: boxfunc4.c:370
void pixcmapDestroy(PIXCMAP **pcmap)
pixcmapDestroy()
Definition: colormap.c:279
l_int32 pixcmapGetCount(const PIXCMAP *cmap)
pixcmapGetCount()
Definition: colormap.c:708
PIXCMAP * pixcmapCreateRandom(l_int32 depth, l_int32 hasblack, l_int32 haswhite)
pixcmapCreateRandom()
Definition: colormap.c:172
l_ok pixcmapAddNewColor(PIXCMAP *cmap, l_int32 rval, l_int32 gval, l_int32 bval, l_int32 *pindex)
pixcmapAddNewColor()
Definition: colormap.c:496
PIXCMAP * pixcmapCreate(l_int32 depth)
pixcmapCreate()
Definition: colormap.c:125
l_ok pixcmapAddBlackOrWhite(PIXCMAP *cmap, l_int32 color, l_int32 *pindex)
pixcmapAddBlackOrWhite()
Definition: colormap.c:639
l_ok pixcmapGetColor(PIXCMAP *cmap, l_int32 index, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
pixcmapGetColor()
Definition: colormap.c:824
l_ok pixcmapAddColor(PIXCMAP *cmap, l_int32 rval, l_int32 gval, l_int32 bval)
pixcmapAddColor()
Definition: colormap.c:414
BOXA * pixConnComp(PIX *pixs, PIXA **ppixa, l_int32 connectivity)
pixConnComp()
Definition: conncomp.c:151
BOXA * pixConnCompBB(PIX *pixs, l_int32 connectivity)
pixConnCompBB()
Definition: conncomp.c:310
l_ok pixRenderHashBoxaBlend(PIX *pix, BOXA *boxa, l_int32 spacing, l_int32 width, l_int32 orient, l_int32 outline, l_int32 rval, l_int32 gval, l_int32 bval, l_float32 fract)
pixRenderHashBoxaBlend()
Definition: graphics.c:2194
PTAA * generatePtaaBoxa(BOXA *boxa)
generatePtaaBoxa()
Definition: graphics.c:573
l_ok pixRenderBoxArb(PIX *pix, BOX *box, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval)
pixRenderBoxArb()
Definition: graphics.c:1655
l_ok pixRenderBoxaArb(PIX *pix, BOXA *boxa, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval)
pixRenderBoxaArb()
Definition: graphics.c:1772
PIX * pixRenderRandomCmapPtaa(PIX *pix, PTAA *ptaa, l_int32 polyflag, l_int32 width, l_int32 closeflag)
pixRenderRandomCmapPtaa()
Definition: graphics.c:2437
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:478
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:366
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
NUMA * numaGetSortIndex(NUMA *na, l_int32 sortorder)
numaGetSortIndex()
Definition: numafunc1.c:2751
void ** pixGetLinePtrs(PIX *pix, l_int32 *psize)
pixGetLinePtrs()
Definition: pix1.c:1949
l_ok pixSetColormap(PIX *pix, PIXCMAP *colormap)
pixSetColormap()
Definition: pix1.c:1699
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 * pixCreateTemplate(const PIX *pixs)
pixCreateTemplate()
Definition: pix1.c:383
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:315
PIX * pixCopy(PIX *pixd, const PIX *pixs)
pixCopy()
Definition: pix1.c:705
l_ok pixSetInRectArbitrary(PIX *pix, BOX *box, l_uint32 val)
pixSetInRectArbitrary()
Definition: pix2.c:1195
l_ok pixClearInRect(PIX *pix, BOX *box)
pixClearInRect()
Definition: pix2.c:1118
l_ok pixSetInRect(PIX *pix, BOX *box)
pixSetInRect()
Definition: pix2.c:1153
l_ok pixSetAll(PIX *pix)
pixSetAll()
Definition: pix2.c:817
l_ok pixBlendInRect(PIX *pixs, BOX *box, l_uint32 val, l_float32 fract)
pixBlendInRect()
Definition: pix2.c:1296
l_ok composeRGBPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_uint32 *ppixel)
composeRGBPixel()
Definition: pix2.c:2751
void extractRGBValues(l_uint32 pixel, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
extractRGBValues()
Definition: pix2.c:2820
l_int32 * makePixelSumTab8(void)
makePixelSumTab8()
Definition: pix3.c:2411
l_ok pixPaintThroughMask(PIX *pixd, PIX *pixm, l_int32 x, l_int32 y, l_uint32 val)
pixPaintThroughMask()
Definition: pix3.c:626
l_ok pixCountPixels(PIX *pixs, l_int32 *pcount, l_int32 *tab8)
pixCountPixels()
Definition: pix3.c:1937
PIX * pixAnd(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixAnd()
Definition: pix3.c:1624
PIX * pixXor(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixXor()
Definition: pix3.c:1688
l_ok pixClipBoxToForeground(PIX *pixs, BOX *boxs, PIX **ppixd, BOX **pboxd)
pixClipBoxToForeground()
Definition: pix5.c:1956
@ L_DRAW_RANDOM
Definition: pix.h:230
@ L_DRAW_RED
Definition: pix.h:225
@ L_DRAW_RGB
Definition: pix.h:229
@ L_DRAW_BLUE
Definition: pix.h:227
@ L_DRAW_GREEN
Definition: pix.h:226
#define PIX_DST
Definition: pix.h:331
@ L_FLIP_PIXELS
Definition: pix.h:774
@ L_SET_PIXELS
Definition: pix.h:772
@ L_CLEAR_PIXELS
Definition: pix.h:773
@ L_SELECT_IF_GTE
Definition: pix.h:785
@ L_POS_SLOPE_LINE
Definition: pix.h:1014
@ L_NEG_SLOPE_LINE
Definition: pix.h:1016
@ L_SORT_BY_AREA
Definition: pix.h:744
@ L_SORT_BY_Y
Definition: pix.h:736
@ L_COPY
Definition: pix.h:712
@ L_CLONE
Definition: pix.h:713
@ L_INSERT
Definition: pix.h:711
@ L_SET_WHITE
Definition: pix.h:906
@ L_FROM_BOT
Definition: pix.h:1037
@ L_FROM_LEFT
Definition: pix.h:1034
@ L_SCAN_VERTICAL
Definition: pix.h:1042
@ L_SCAN_HORIZONTAL
Definition: pix.h:1041
@ L_FROM_RIGHT
Definition: pix.h:1035
@ L_FROM_TOP
Definition: pix.h:1036
#define PIX_CLR
Definition: pix.h:333
@ L_SORT_DECREASING
Definition: pix.h:730
@ L_SORT_INCREASING
Definition: pix.h:729
#define PIX_NOT(op)
Definition: pix.h:332
#define PIX_SET
Definition: pix.h:334
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
PIX * pixConvertTo8(PIX *pixs, l_int32 cmapflag)
pixConvertTo8()
Definition: pixconv.c:3133
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3332
PIX * pixConvert1To8(PIX *pixd, PIX *pixs, l_uint8 val0, l_uint8 val1)
pixConvert1To8()
Definition: pixconv.c:2401
void ptaaDestroy(PTAA **pptaa)
ptaaDestroy()
Definition: ptabasic.c:1003
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
Definition: pix.h:481
Definition: pix.h:492
Definition: pix.h:502
Definition: array.h:71
Definition: pix.h:139
Definition: pix.h:456
Definition: pix.h:531
void lept_stderr(const char *fmt,...)
lept_stderr()
Definition: utils1.c:306