Leptonica  1.83.1
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 
69 static 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  *---------------------------------------------------------------------*/
96 PIX *
98  l_int32 connectivity,
99  BOXA **pboxa)
100 {
101 BOXA *boxa;
102 PIX *pixd;
103 
104  if (pboxa) *pboxa = NULL;
105  if (!pixs || pixGetDepth(pixs) != 1)
106  return (PIX *)ERROR_PTR("pixs undefined or not 1 bpp", __func__, NULL);
107  if (connectivity != 4 && connectivity != 8)
108  return (PIX *)ERROR_PTR("connectivity not 4 or 8", __func__, NULL);
109 
110  boxa = pixConnComp(pixs, NULL, connectivity);
111  pixd = pixCreateTemplate(pixs);
112  if (boxaGetCount(boxa) != 0)
113  pixMaskBoxa(pixd, pixd, boxa, L_SET_PIXELS);
114  if (pboxa)
115  *pboxa = boxa;
116  else
117  boxaDestroy(&boxa);
118  return pixd;
119 }
120 
121 
148 PIX *
150  PIX *pixs,
151  BOXA *boxa,
152  l_int32 op)
153 {
154 l_int32 i, n, x, y, w, h;
155 BOX *box;
156 
157  if (!pixs)
158  return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
159  if (pixGetColormap(pixs))
160  return (PIX *)ERROR_PTR("pixs is cmapped", __func__, NULL);
161  if (pixd && (pixd != pixs))
162  return (PIX *)ERROR_PTR("if pixd, must be in-place", __func__, NULL);
163  if (!boxa)
164  return (PIX *)ERROR_PTR("boxa not defined", __func__, NULL);
165  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
166  return (PIX *)ERROR_PTR("invalid op", __func__, NULL);
167 
168  pixd = pixCopy(pixd, pixs);
169  if ((n = boxaGetCount(boxa)) == 0) {
170  L_WARNING("no boxes to mask\n", __func__);
171  return pixd;
172  }
173 
174  for (i = 0; i < n; i++) {
175  box = boxaGetBox(boxa, i, L_CLONE);
176  boxGetGeometry(box, &x, &y, &w, &h);
177  if (op == L_SET_PIXELS)
178  pixRasterop(pixd, x, y, w, h, PIX_SET, NULL, 0, 0);
179  else if (op == L_CLEAR_PIXELS)
180  pixRasterop(pixd, x, y, w, h, PIX_CLR, NULL, 0, 0);
181  else /* op == L_FLIP_PIXELS */
182  pixRasterop(pixd, x, y, w, h, PIX_NOT(PIX_DST), NULL, 0, 0);
183  boxDestroy(&box);
184  }
185 
186  return pixd;
187 }
188 
189 
215 PIX *
217  BOXA *boxa,
218  l_uint32 val)
219 {
220 l_int32 i, n, d, rval, gval, bval, newindex;
221 l_int32 mapvacancy; /* true only if cmap and not full */
222 BOX *box;
223 PIX *pixd;
224 PIXCMAP *cmap;
225 
226  if (!pixs)
227  return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
228  if (!boxa)
229  return (PIX *)ERROR_PTR("boxa not defined", __func__, NULL);
230 
231  if ((n = boxaGetCount(boxa)) == 0) {
232  L_WARNING("no boxes to paint; returning a copy\n", __func__);
233  return pixCopy(NULL, pixs);
234  }
235 
236  mapvacancy = FALSE;
237  if ((cmap = pixGetColormap(pixs)) != NULL) {
238  if (pixcmapGetCount(cmap) < 256)
239  mapvacancy = TRUE;
240  }
241  if (pixGetDepth(pixs) == 1 || mapvacancy)
242  pixd = pixConvertTo8(pixs, TRUE);
243  else
244  pixd = pixConvertTo32(pixs);
245  if (!pixd)
246  return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
247 
248  d = pixGetDepth(pixd);
249  if (d == 8) { /* colormapped */
250  cmap = pixGetColormap(pixd);
251  extractRGBValues(val, &rval, &gval, &bval);
252  if (pixcmapAddNewColor(cmap, rval, gval, bval, &newindex)) {
253  pixDestroy(&pixd);
254  return (PIX *)ERROR_PTR("cmap full; can't add", __func__, NULL);
255  }
256  }
257 
258  for (i = 0; i < n; i++) {
259  box = boxaGetBox(boxa, i, L_CLONE);
260  if (d == 8)
261  pixSetInRectArbitrary(pixd, box, newindex);
262  else
263  pixSetInRectArbitrary(pixd, box, val);
264  boxDestroy(&box);
265  }
266 
267  return pixd;
268 }
269 
270 
279 PIX *
281  BOXA *boxa,
282  l_int32 op)
283 {
284 l_int32 i, n, d, index;
285 l_uint32 color;
286 BOX *box;
287 PIX *pixd;
288 PIXCMAP *cmap;
289 
290  if (!pixs)
291  return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
292  if (!boxa)
293  return pixCopy(NULL, pixs);
294  if ((n = boxaGetCount(boxa)) == 0)
295  return pixCopy(NULL, pixs);
296 
297  pixd = pixCopy(NULL, pixs);
298  d = pixGetDepth(pixd);
299  if (d == 1) {
300  for (i = 0; i < n; i++) {
301  box = boxaGetBox(boxa, i, L_CLONE);
302  if (op == L_SET_WHITE)
303  pixClearInRect(pixd, box);
304  else
305  pixSetInRect(pixd, box);
306  boxDestroy(&box);
307  }
308  return pixd;
309  }
310 
311  cmap = pixGetColormap(pixs);
312  if (cmap) {
313  color = (op == L_SET_WHITE) ? 1 : 0;
314  pixcmapAddBlackOrWhite(cmap, color, &index);
315  } else if (d == 8) {
316  color = (op == L_SET_WHITE) ? 0xff : 0x0;
317  } else if (d == 32) {
318  color = (op == L_SET_WHITE) ? 0xffffff00 : 0x0;
319  } else if (d == 2) {
320  color = (op == L_SET_WHITE) ? 0x3 : 0x0;
321  } else if (d == 4) {
322  color = (op == L_SET_WHITE) ? 0xf : 0x0;
323  } else if (d == 16) {
324  color = (op == L_SET_WHITE) ? 0xffff : 0x0;
325  } else {
326  pixDestroy(&pixd);
327  return (PIX *)ERROR_PTR("invalid depth", __func__, NULL);
328  }
329 
330  for (i = 0; i < n; i++) {
331  box = boxaGetBox(boxa, i, L_CLONE);
332  if (cmap)
333  pixSetInRectArbitrary(pixd, box, index);
334  else
335  pixSetInRectArbitrary(pixd, box, color);
336  boxDestroy(&box);
337  }
338 
339  return pixd;
340 }
341 
342 
358 PIX *
360  BOXA *boxa)
361 {
362 l_int32 i, n, d, rval, gval, bval, index;
363 l_uint32 val;
364 BOX *box;
365 PIX *pixd;
366 PIXCMAP *cmap;
367 
368  if (!pixs)
369  return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
370  if (!boxa)
371  return (PIX *)ERROR_PTR("boxa not defined", __func__, NULL);
372 
373  if ((n = boxaGetCount(boxa)) == 0) {
374  L_WARNING("no boxes to paint; returning a copy\n", __func__);
375  return pixCopy(NULL, pixs);
376  }
377 
378  if (pixGetDepth(pixs) == 1)
379  pixd = pixConvert1To8(NULL, pixs, 255, 0);
380  else
381  pixd = pixConvertTo32(pixs);
382  if (!pixd)
383  return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
384 
385  cmap = pixcmapCreateRandom(8, 1, 1);
386  d = pixGetDepth(pixd); /* either 8 or 32 */
387  if (d == 8) /* colormapped */
388  pixSetColormap(pixd, cmap);
389 
390  for (i = 0; i < n; i++) {
391  box = boxaGetBox(boxa, i, L_CLONE);
392  index = 1 + (i % 254);
393  if (d == 8) {
394  pixSetInRectArbitrary(pixd, box, index);
395  } else { /* d == 32 */
396  pixcmapGetColor(cmap, index, &rval, &gval, &bval);
397  composeRGBPixel(rval, gval, bval, &val);
398  pixSetInRectArbitrary(pixd, box, val);
399  }
400  boxDestroy(&box);
401  }
402 
403  if (d == 32)
404  pixcmapDestroy(&cmap);
405  return pixd;
406 }
407 
408 
427 PIX *
429  BOXA *boxa,
430  l_float32 fract)
431 {
432 l_int32 i, n, rval, gval, bval, index;
433 l_uint32 val;
434 BOX *box;
435 PIX *pixd;
436 PIXCMAP *cmap;
437 
438  if (!pixs)
439  return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
440  if (!boxa)
441  return (PIX *)ERROR_PTR("boxa not defined", __func__, NULL);
442  if (fract < 0.0 || fract > 1.0) {
443  L_WARNING("fract must be in [0.0, 1.0]; setting to 0.5\n", __func__);
444  fract = 0.5;
445  }
446 
447  if ((n = boxaGetCount(boxa)) == 0) {
448  L_WARNING("no boxes to paint; returning a copy\n", __func__);
449  return pixCopy(NULL, pixs);
450  }
451 
452  if ((pixd = pixConvertTo32(pixs)) == NULL)
453  return (PIX *)ERROR_PTR("pixd not defined", __func__, NULL);
454 
455  cmap = pixcmapCreateRandom(8, 1, 1);
456  for (i = 0; i < n; i++) {
457  box = boxaGetBox(boxa, i, L_CLONE);
458  index = 1 + (i % 254);
459  pixcmapGetColor(cmap, index, &rval, &gval, &bval);
460  composeRGBPixel(rval, gval, bval, &val);
461  pixBlendInRect(pixd, box, val, fract);
462  boxDestroy(&box);
463  }
464 
465  pixcmapDestroy(&cmap);
466  return pixd;
467 }
468 
469 
486 PIX *
488  BOXA *boxa,
489  l_int32 width,
490  l_uint32 val)
491 {
492 l_int32 rval, gval, bval, newindex;
493 l_int32 mapvacancy; /* true only if cmap and not full */
494 PIX *pixd;
495 PIXCMAP *cmap;
496 
497  if (!pixs)
498  return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
499  if (!boxa)
500  return (PIX *)ERROR_PTR("boxa not defined", __func__, NULL);
501  if (width < 1)
502  return (PIX *)ERROR_PTR("width must be >= 1", __func__, NULL);
503 
504  if (boxaGetCount(boxa) == 0) {
505  L_WARNING("no boxes to draw; returning a copy\n", __func__);
506  return pixCopy(NULL, pixs);
507  }
508 
509  mapvacancy = FALSE;
510  if ((cmap = pixGetColormap(pixs)) != NULL) {
511  if (pixcmapGetCount(cmap) < 256)
512  mapvacancy = TRUE;
513  }
514  if (pixGetDepth(pixs) == 1 || mapvacancy)
515  pixd = pixConvertTo8(pixs, TRUE);
516  else
517  pixd = pixConvertTo32(pixs);
518  if (!pixd)
519  return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
520 
521  extractRGBValues(val, &rval, &gval, &bval);
522  if (pixGetDepth(pixd) == 8) { /* colormapped */
523  cmap = pixGetColormap(pixd);
524  pixcmapAddNewColor(cmap, rval, gval, bval, &newindex);
525  }
526 
527  pixRenderBoxaArb(pixd, boxa, width, rval, gval, bval);
528  return pixd;
529 }
530 
531 
548 PIX *
550  BOXA *boxa,
551  l_int32 width)
552 {
553 l_int32 i, n, rval, gval, bval, index;
554 BOX *box;
555 PIX *pixd;
556 PIXCMAP *cmap;
557 PTAA *ptaa;
558 
559  if (!pixs)
560  return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
561  if (!boxa)
562  return (PIX *)ERROR_PTR("boxa not defined", __func__, NULL);
563  if (width < 1)
564  return (PIX *)ERROR_PTR("width must be >= 1", __func__, NULL);
565 
566  if ((n = boxaGetCount(boxa)) == 0) {
567  L_WARNING("no boxes to draw; returning a copy\n", __func__);
568  return pixCopy(NULL, pixs);
569  }
570 
571  /* Input depth = 1 bpp; generate cmapped output */
572  if (pixGetDepth(pixs) == 1) {
573  ptaa = generatePtaaBoxa(boxa);
574  pixd = pixRenderRandomCmapPtaa(pixs, ptaa, 1, width, 1);
575  ptaaDestroy(&ptaa);
576  return pixd;
577  }
578 
579  /* Generate rgb output */
580  pixd = pixConvertTo32(pixs);
581  cmap = pixcmapCreateRandom(8, 1, 1);
582  for (i = 0; i < n; i++) {
583  box = boxaGetBox(boxa, i, L_CLONE);
584  index = 1 + (i % 254);
585  pixcmapGetColor(cmap, index, &rval, &gval, &bval);
586  pixRenderBoxArb(pixd, box, width, rval, gval, bval);
587  boxDestroy(&box);
588  }
589  pixcmapDestroy(&cmap);
590  return pixd;
591 }
592 
593 
620 PIX *
622  BOXAA *baa,
623  l_int32 linewba,
624  l_int32 linewb,
625  l_uint32 colorba,
626  l_uint32 colorb,
627  l_int32 w,
628  l_int32 h)
629 {
630 l_int32 i, j, n, m, rbox, gbox, bbox, rboxa, gboxa, bboxa;
631 BOX *box;
632 BOXA *boxa;
633 PIX *pixd;
634 PIXCMAP *cmap;
635 
636  if (!baa)
637  return (PIX *)ERROR_PTR("baa not defined", __func__, NULL);
638 
639  if (w <= 0 || h <= 0) {
640  if (pixs)
641  pixGetDimensions(pixs, &w, &h, NULL);
642  else
643  boxaaGetExtent(baa, &w, &h, NULL, NULL);
644  }
645 
646  if (pixs) {
647  pixd = pixConvertTo8(pixs, 1);
648  cmap = pixGetColormap(pixd);
649  } else {
650  pixd = pixCreate(w, h, 8);
651  cmap = pixcmapCreate(8);
652  pixSetColormap(pixd, cmap);
653  pixcmapAddColor(cmap, 255, 255, 255);
654  }
655  extractRGBValues(colorb, &rbox, &gbox, &bbox);
656  extractRGBValues(colorba, &rboxa, &gboxa, &bboxa);
657  pixcmapAddColor(cmap, rbox, gbox, bbox);
658  pixcmapAddColor(cmap, rboxa, gboxa, bboxa);
659 
660  n = boxaaGetCount(baa);
661  for (i = 0; i < n; i++) {
662  boxa = boxaaGetBoxa(baa, i, L_CLONE);
663  boxaGetExtent(boxa, NULL, NULL, &box);
664  pixRenderBoxArb(pixd, box, linewba, rboxa, gboxa, bboxa);
665  boxDestroy(&box);
666  m = boxaGetCount(boxa);
667  for (j = 0; j < m; j++) {
668  box = boxaGetBox(boxa, j, L_CLONE);
669  pixRenderBoxArb(pixd, box, linewb, rbox, gbox, bbox);
670  boxDestroy(&box);
671  }
672  boxaDestroy(&boxa);
673  }
674 
675  return pixd;
676 }
677 
678 
700 PIXA *
702  BOXAA *baa,
703  l_int32 colorflag,
704  l_int32 width)
705 {
706 l_int32 i, j, nba, n, nbox, rval, gval, bval;
707 l_uint32 color;
708 l_uint32 colors[255];
709 BOXA *boxa;
710 BOX *box;
711 PIX *pix;
712 PIXA *pixad;
713 
714  if (!pixas)
715  return (PIXA *)ERROR_PTR("pixas not defined", __func__, NULL);
716  if (!baa)
717  return (PIXA *)ERROR_PTR("baa not defined", __func__, NULL);
718  if (width < 1)
719  return (PIXA *)ERROR_PTR("width must be >= 1", __func__, NULL);
720  if ((nba = boxaaGetCount(baa)) < 1)
721  return (PIXA *)ERROR_PTR("no boxa in baa", __func__, NULL);
722  if ((n = pixaGetCount(pixas)) == 0)
723  return (PIXA *)ERROR_PTR("no pix in pixas", __func__, NULL);
724  if (n != nba)
725  return (PIXA *)ERROR_PTR("num pix != num boxa", __func__, NULL);
726  if (colorflag == L_DRAW_RED)
727  color = 0xff000000;
728  else if (colorflag == L_DRAW_GREEN)
729  color = 0x00ff0000;
730  else if (colorflag == L_DRAW_BLUE)
731  color = 0x0000ff00;
732  else if (colorflag == L_DRAW_RGB)
733  color = 0x000000ff;
734  else if (colorflag == L_DRAW_RANDOM)
735  color = 0x00000000;
736  else
737  return (PIXA *)ERROR_PTR("invalid colorflag", __func__, NULL);
738 
739  if (colorflag == L_DRAW_RED || colorflag == L_DRAW_GREEN ||
740  colorflag == L_DRAW_BLUE) {
741  for (i = 0; i < 255; i++)
742  colors[i] = color;
743  } else if (colorflag == L_DRAW_RGB) {
744  for (i = 0; i < 255; i++) {
745  if (i % 3 == L_DRAW_RED)
746  colors[i] = 0xff000000;
747  else if (i % 3 == L_DRAW_GREEN)
748  colors[i] = 0x00ff0000;
749  else /* i % 3 == L_DRAW_BLUE) */
750  colors[i] = 0x0000ff00;
751  }
752  } else if (colorflag == L_DRAW_RANDOM) {
753  for (i = 0; i < 255; i++) {
754  rval = (l_uint32)rand() & 0xff;
755  gval = (l_uint32)rand() & 0xff;
756  bval = (l_uint32)rand() & 0xff;
757  composeRGBPixel(rval, gval, bval, &colors[i]);
758  }
759  }
760 
761  pixad = pixaCreate(n);
762  for (i = 0; i < n; i++) {
763  pix = pixaGetPix(pixas, i, L_COPY);
764  boxa = boxaaGetBoxa(baa, i, L_CLONE);
765  nbox = boxaGetCount(boxa);
766  for (j = 0; j < nbox; j++) {
767  box = boxaGetBox(boxa, j, L_CLONE);
768  extractRGBValues(colors[j % 255], &rval, &gval, &bval);
769  pixRenderBoxArb(pix, box, width, rval, gval, bval);
770  boxDestroy(&box);
771  }
772  boxaDestroy(&boxa);
773  pixaAddPix(pixad, pix, L_INSERT);
774  }
775 
776  return pixad;
777 }
778 
779 
780 /*---------------------------------------------------------------------*
781  * Split mask components into Boxa *
782  *---------------------------------------------------------------------*/
817 BOXA *
819  l_int32 minsum,
820  l_int32 skipdist,
821  l_int32 delta,
822  l_int32 maxbg,
823  l_int32 maxcomps,
824  l_int32 remainder)
825 {
826 l_int32 i, n;
827 BOX *box;
828 BOXA *boxa, *boxas, *boxad;
829 PIX *pix;
830 PIXA *pixas;
831 
832  if (!pixs || pixGetDepth(pixs) != 1)
833  return (BOXA *)ERROR_PTR("pixs undefined or not 1 bpp", __func__, NULL);
834 
835  boxas = pixConnComp(pixs, &pixas, 8);
836  n = boxaGetCount(boxas);
837  boxad = boxaCreate(0);
838  for (i = 0; i < n; i++) {
839  pix = pixaGetPix(pixas, i, L_CLONE);
840  box = boxaGetBox(boxas, i, L_CLONE);
841  boxa = pixSplitComponentIntoBoxa(pix, box, minsum, skipdist,
842  delta, maxbg, maxcomps, remainder);
843  boxaJoin(boxad, boxa, 0, -1);
844  pixDestroy(&pix);
845  boxDestroy(&box);
846  boxaDestroy(&boxa);
847  }
848 
849  pixaDestroy(&pixas);
850  boxaDestroy(&boxas);
851  return boxad;
852 }
853 
854 
924 BOXA *
926  BOX *box,
927  l_int32 minsum,
928  l_int32 skipdist,
929  l_int32 delta,
930  l_int32 maxbg,
931  l_int32 maxcomps,
932  l_int32 remainder)
933 {
934 l_int32 i, w, h, boxx, boxy, bx, by, bw, bh, maxdir, maxscore;
935 l_int32 iter;
936 BOX *boxs; /* shrinks as rectangular regions are removed */
937 BOX *boxt1, *boxt2, *boxt3;
938 BOXA *boxat; /* stores rectangle data for each side in an iteration */
939 BOXA *boxad;
940 NUMA *nascore, *nas;
941 PIX *pixs;
942 
943  if (!pix || pixGetDepth(pix) != 1)
944  return (BOXA *)ERROR_PTR("pix undefined or not 1 bpp", __func__, NULL);
945 
946  pixs = pixCopy(NULL, pix);
947  pixGetDimensions(pixs, &w, &h, NULL);
948  if (box)
949  boxGetGeometry(box, &boxx, &boxy, NULL, NULL);
950  else
951  boxx = boxy = 0;
952  boxs = boxCreate(0, 0, w, h);
953  boxad = boxaCreate(0);
954 
955  iter = 0;
956  while (boxs != NULL) {
957  boxGetGeometry(boxs, &bx, &by, &bw, &bh);
958  boxat = boxaCreate(4); /* potential rectangular regions */
959  nascore = numaCreate(4);
960  for (i = 0; i < 4; i++) {
961  pixSearchForRectangle(pixs, boxs, minsum, skipdist, delta, maxbg,
962  i, boxat, nascore);
963  }
964  nas = numaGetSortIndex(nascore, L_SORT_DECREASING);
965  numaGetIValue(nas, 0, &maxdir);
966  numaGetIValue(nascore, maxdir, &maxscore);
967 #if DEBUG_SPLIT
968  lept_stderr("Iteration: %d\n", iter);
969  boxPrintStreamInfo(stderr, boxs);
970  boxaWriteStderr(boxat);
971  lept_stderr("\nmaxdir = %d, maxscore = %d\n\n", maxdir, maxscore);
972 #endif /* DEBUG_SPLIT */
973  if (maxscore > 0) { /* accept this */
974  boxt1 = boxaGetBox(boxat, maxdir, L_CLONE);
975  boxt2 = boxTransform(boxt1, boxx, boxy, 1.0, 1.0);
976  boxaAddBox(boxad, boxt2, L_INSERT);
977  pixClearInRect(pixs, boxt1);
978  boxDestroy(&boxt1);
979  pixClipBoxToForeground(pixs, boxs, NULL, &boxt3);
980  boxDestroy(&boxs);
981  boxs = boxt3;
982  if (boxs) {
983  boxGetGeometry(boxs, NULL, NULL, &bw, &bh);
984  if (bw < 2 || bh < 2)
985  boxDestroy(&boxs); /* we're done */
986  }
987  } else { /* no more valid rectangles can be found */
988  if (remainder == 1) { /* save the last box */
989  boxt1 = boxTransform(boxs, boxx, boxy, 1.0, 1.0);
990  boxaAddBox(boxad, boxt1, L_INSERT);
991  }
992  boxDestroy(&boxs); /* we're done */
993  }
994  boxaDestroy(&boxat);
995  numaDestroy(&nascore);
996  numaDestroy(&nas);
997 
998  iter++;
999  if ((iter == maxcomps) && boxs) {
1000  if (remainder == 1) { /* save the last box */
1001  boxt1 = boxTransform(boxs, boxx, boxy, 1.0, 1.0);
1002  boxaAddBox(boxad, boxt1, L_INSERT);
1003  }
1004  boxDestroy(&boxs); /* we're done */
1005  }
1006  }
1007 
1008  pixDestroy(&pixs);
1009  return boxad;
1010 }
1011 
1012 
1037 static l_int32
1039  BOX *boxs,
1040  l_int32 minsum,
1041  l_int32 skipdist,
1042  l_int32 delta,
1043  l_int32 maxbg,
1044  l_int32 sideflag,
1045  BOXA *boxat,
1046  NUMA *nascore)
1047 {
1048 l_int32 bx, by, bw, bh, width, height, setref, atref;
1049 l_int32 minincol, maxincol, mininrow, maxinrow, minval, maxval, bgref;
1050 l_int32 x, y, x0, y0, xref, yref, colsum, rowsum, score, countref, diff;
1051 void **lines1;
1052 BOX *boxr;
1053 
1054  if (!pixs || pixGetDepth(pixs) != 1)
1055  return ERROR_INT("pixs undefined or not 1 bpp", __func__, 1);
1056  if (!boxs)
1057  return ERROR_INT("boxs not defined", __func__, 1);
1058  if (!boxat)
1059  return ERROR_INT("boxat not defined", __func__, 1);
1060  if (!nascore)
1061  return ERROR_INT("nascore not defined", __func__, 1);
1062 
1063  lines1 = pixGetLinePtrs(pixs, NULL);
1064  boxGetGeometry(boxs, &bx, &by, &bw, &bh);
1065  boxr = NULL;
1066  setref = 0;
1067  atref = 0;
1068  maxval = 0;
1069  minval = 100000;
1070  score = 0; /* sum of all (fg - bg) pixels seen in the scan */
1071  xref = yref = 100000; /* init to impossibly big number */
1072  if (sideflag == L_FROM_LEFT) {
1073  for (x = bx; x < bx + bw; x++) {
1074  colsum = 0;
1075  maxincol = 0;
1076  minincol = 100000;
1077  for (y = by; y < by + bh; y++) {
1078  if (GET_DATA_BIT(lines1[y], x)) {
1079  colsum++;
1080  if (y > maxincol) maxincol = y;
1081  if (y < minincol) minincol = y;
1082  }
1083  }
1084  score += colsum;
1085 
1086  /* Enough fg to sweep out a rectangle? */
1087  if (!setref && colsum >= minsum) {
1088  setref = 1;
1089  xref = x + 10;
1090  if (xref >= bx + bw)
1091  goto failure;
1092  }
1093 
1094  /* Reached the reference line; save the count;
1095  * if there is too much bg, the rectangle is invalid. */
1096  if (setref && x == xref) {
1097  atref = 1;
1098  countref = colsum;
1099  bgref = maxincol - minincol + 1 - countref;
1100  if (bgref > maxbg)
1101  goto failure;
1102  }
1103 
1104  /* Have we left the rectangle? If so, save it along
1105  * with the score. */
1106  if (atref) {
1107  diff = L_ABS(colsum - countref);
1108  if (diff >= delta || x == bx + bw - 1) {
1109  height = maxval - minval + 1;
1110  width = x - bx;
1111  if (x == bx + bw - 1) width = x - bx + 1;
1112  boxr = boxCreate(bx, minval, width, height);
1113  score = 2 * score - width * height;
1114  goto success;
1115  }
1116  }
1117  maxval = L_MAX(maxval, maxincol);
1118  minval = L_MIN(minval, minincol);
1119  }
1120  goto failure;
1121  } else if (sideflag == L_FROM_RIGHT) {
1122  for (x = bx + bw - 1; x >= bx; x--) {
1123  colsum = 0;
1124  maxincol = 0;
1125  minincol = 100000;
1126  for (y = by; y < by + bh; y++) {
1127  if (GET_DATA_BIT(lines1[y], x)) {
1128  colsum++;
1129  if (y > maxincol) maxincol = y;
1130  if (y < minincol) minincol = y;
1131  }
1132  }
1133  score += colsum;
1134  if (!setref && colsum >= minsum) {
1135  setref = 1;
1136  xref = x - 10;
1137  if (xref < bx)
1138  goto failure;
1139  }
1140  if (setref && x == xref) {
1141  atref = 1;
1142  countref = colsum;
1143  bgref = maxincol - minincol + 1 - countref;
1144  if (bgref > maxbg)
1145  goto failure;
1146  }
1147  if (atref) {
1148  diff = L_ABS(colsum - countref);
1149  if (diff >= delta || x == bx) {
1150  height = maxval - minval + 1;
1151  x0 = x + 1;
1152  if (x == bx) x0 = x;
1153  width = bx + bw - x0;
1154  boxr = boxCreate(x0, minval, width, height);
1155  score = 2 * score - width * height;
1156  goto success;
1157  }
1158  }
1159  maxval = L_MAX(maxval, maxincol);
1160  minval = L_MIN(minval, minincol);
1161  }
1162  goto failure;
1163  } else if (sideflag == L_FROM_TOP) {
1164  for (y = by; y < by + bh; y++) {
1165  rowsum = 0;
1166  maxinrow = 0;
1167  mininrow = 100000;
1168  for (x = bx; x < bx + bw; x++) {
1169  if (GET_DATA_BIT(lines1[y], x)) {
1170  rowsum++;
1171  if (x > maxinrow) maxinrow = x;
1172  if (x < mininrow) mininrow = x;
1173  }
1174  }
1175  score += rowsum;
1176  if (!setref && rowsum >= minsum) {
1177  setref = 1;
1178  yref = y + 10;
1179  if (yref >= by + bh)
1180  goto failure;
1181  }
1182  if (setref && y == yref) {
1183  atref = 1;
1184  countref = rowsum;
1185  bgref = maxinrow - mininrow + 1 - countref;
1186  if (bgref > maxbg)
1187  goto failure;
1188  }
1189  if (atref) {
1190  diff = L_ABS(rowsum - countref);
1191  if (diff >= delta || y == by + bh - 1) {
1192  width = maxval - minval + 1;
1193  height = y - by;
1194  if (y == by + bh - 1) height = y - by + 1;
1195  boxr = boxCreate(minval, by, width, height);
1196  score = 2 * score - width * height;
1197  goto success;
1198  }
1199  }
1200  maxval = L_MAX(maxval, maxinrow);
1201  minval = L_MIN(minval, mininrow);
1202  }
1203  goto failure;
1204  } else if (sideflag == L_FROM_BOT) {
1205  for (y = by + bh - 1; y >= by; y--) {
1206  rowsum = 0;
1207  maxinrow = 0;
1208  mininrow = 100000;
1209  for (x = bx; x < bx + bw; x++) {
1210  if (GET_DATA_BIT(lines1[y], x)) {
1211  rowsum++;
1212  if (x > maxinrow) maxinrow = x;
1213  if (x < mininrow) mininrow = x;
1214  }
1215  }
1216  score += rowsum;
1217  if (!setref && rowsum >= minsum) {
1218  setref = 1;
1219  yref = y - 10;
1220  if (yref < by)
1221  goto failure;
1222  }
1223  if (setref && y == yref) {
1224  atref = 1;
1225  countref = rowsum;
1226  bgref = maxinrow - mininrow + 1 - countref;
1227  if (bgref > maxbg)
1228  goto failure;
1229  }
1230  if (atref) {
1231  diff = L_ABS(rowsum - countref);
1232  if (diff >= delta || y == by) {
1233  width = maxval - minval + 1;
1234  y0 = y + 1;
1235  if (y == by) y0 = y;
1236  height = by + bh - y0;
1237  boxr = boxCreate(minval, y0, width, height);
1238  score = 2 * score - width * height;
1239  goto success;
1240  }
1241  }
1242  maxval = L_MAX(maxval, maxinrow);
1243  minval = L_MIN(minval, mininrow);
1244  }
1245  goto failure;
1246  }
1247 
1248 failure:
1249  numaAddNumber(nascore, 0);
1250  boxaAddBox(boxat, boxCreate(0, 0, 1, 1), L_INSERT); /* min box */
1251  LEPT_FREE(lines1);
1252  return 0;
1253 
1254 success:
1255  numaAddNumber(nascore, score);
1256  boxaAddBox(boxat, boxr, L_INSERT);
1257  LEPT_FREE(lines1);
1258  return 0;
1259 }
1260 
1261 
1262 /*---------------------------------------------------------------------*
1263  * Represent horizontal or vertical mosaic strips *
1264  *---------------------------------------------------------------------*/
1284 BOXA *
1286  l_int32 h,
1287  l_int32 direction,
1288  l_int32 size)
1289 {
1290 l_int32 i, nstrips, extra;
1291 BOX *box;
1292 BOXA *boxa;
1293 
1294  if (w < 1 || h < 1)
1295  return (BOXA *)ERROR_PTR("invalid w or h", __func__, NULL);
1296  if (direction != L_SCAN_HORIZONTAL && direction != L_SCAN_VERTICAL)
1297  return (BOXA *)ERROR_PTR("invalid direction", __func__, NULL);
1298  if (size < 1)
1299  return (BOXA *)ERROR_PTR("size < 1", __func__, NULL);
1300 
1301  boxa = boxaCreate(0);
1302  if (direction == L_SCAN_HORIZONTAL) {
1303  nstrips = w / size;
1304  for (i = 0; i < nstrips; i++) {
1305  box = boxCreate(i * size, 0, size, h);
1306  boxaAddBox(boxa, box, L_INSERT);
1307  }
1308  if ((extra = w % size) > 0) {
1309  box = boxCreate(nstrips * size, 0, extra, h);
1310  boxaAddBox(boxa, box, L_INSERT);
1311  }
1312  } else {
1313  nstrips = h / size;
1314  for (i = 0; i < nstrips; i++) {
1315  box = boxCreate(0, i * size, w, size);
1316  boxaAddBox(boxa, box, L_INSERT);
1317  }
1318  if ((extra = h % size) > 0) {
1319  box = boxCreate(0, nstrips * size, w, extra);
1320  boxaAddBox(boxa, box, L_INSERT);
1321  }
1322  }
1323  return boxa;
1324 }
1325 
1326 
1327 /*---------------------------------------------------------------------*
1328  * Comparison between boxa *
1329  *---------------------------------------------------------------------*/
1361 l_ok
1363  BOXA *boxa2,
1364  l_int32 areathresh,
1365  l_int32 *pnsame,
1366  l_float32 *pdiffarea,
1367  l_float32 *pdiffxor,
1368  PIX **ppixdb)
1369 {
1370 l_int32 w, h, x3, y3, w3, h3, x4, y4, w4, h4, n3, n4, area1, area2;
1371 l_int32 count3, count4, countxor;
1372 l_int32 *tab;
1373 BOX *box3, *box4;
1374 BOXA *boxa3, *boxa4, *boxa3t, *boxa4t;
1375 PIX *pix1, *pix2, *pix3, *pix4, *pix5;
1376 PIXA *pixa;
1377 
1378  if (pdiffxor) *pdiffxor = 1.0;
1379  if (ppixdb) *ppixdb = NULL;
1380  if (pnsame) *pnsame = FALSE;
1381  if (pdiffarea) *pdiffarea = 1.0;
1382  if (!boxa1 || !boxa2)
1383  return ERROR_INT("boxa1 and boxa2 not both defined", __func__, 1);
1384  if (!pnsame)
1385  return ERROR_INT("&nsame not defined", __func__, 1);
1386  if (!pdiffarea)
1387  return ERROR_INT("&diffarea not defined", __func__, 1);
1388 
1389  boxa3 = boxaSelectByArea(boxa1, areathresh, L_SELECT_IF_GTE, NULL);
1390  boxa4 = boxaSelectByArea(boxa2, areathresh, L_SELECT_IF_GTE, NULL);
1391  n3 = boxaGetCount(boxa3);
1392  n4 = boxaGetCount(boxa4);
1393  if (n3 == n4)
1394  *pnsame = TRUE;
1395 
1396  /* There are no boxes in one or both */
1397  if (n3 == 0 || n4 == 0) {
1398  boxaDestroy(&boxa3);
1399  boxaDestroy(&boxa4);
1400  if (n3 == 0 && n4 == 0) { /* they are both empty: we say they are the
1401  * same; otherwise, they differ maximally
1402  * and retain the default value. */
1403  *pdiffarea = 0.0;
1404  if (pdiffxor) *pdiffxor = 0.0;
1405  }
1406  return 0;
1407  }
1408 
1409  /* There are boxes in both */
1410  boxaGetArea(boxa3, &area1);
1411  boxaGetArea(boxa4, &area2);
1412  *pdiffarea = (l_float32)L_ABS(area1 - area2) / (l_float32)(area1 + area2);
1413  if (!pdiffxor) {
1414  boxaDestroy(&boxa3);
1415  boxaDestroy(&boxa4);
1416  return 0;
1417  }
1418 
1419  /* The easiest way to get the xor of aligned boxes is to work
1420  * with images of each boxa. This is done by translating each
1421  * boxa so that the UL corner of the region that includes all
1422  * boxes in the boxa is placed at the origin of each pix. */
1423  boxaGetExtent(boxa3, &w, &h, &box3);
1424  boxaGetExtent(boxa4, &w, &h, &box4);
1425  boxGetGeometry(box3, &x3, &y3, &w3, &h3);
1426  boxGetGeometry(box4, &x4, &y4, &w4, &h4);
1427  boxa3t = boxaTransform(boxa3, -x3, -y3, 1.0, 1.0);
1428  boxa4t = boxaTransform(boxa4, -x4, -y4, 1.0, 1.0);
1429  w = L_MAX(x3 + w3, x4 + w4);
1430  h = L_MAX(y3 + h3, y4 + h4);
1431  pix3 = pixCreate(w, h, 1); /* use the max to keep everything in the xor */
1432  pix4 = pixCreate(w, h, 1);
1433  pixMaskBoxa(pix3, pix3, boxa3t, L_SET_PIXELS);
1434  pixMaskBoxa(pix4, pix4, boxa4t, L_SET_PIXELS);
1435  tab = makePixelSumTab8();
1436  pixCountPixels(pix3, &count3, tab);
1437  pixCountPixels(pix4, &count4, tab);
1438  pix5 = pixXor(NULL, pix3, pix4);
1439  pixCountPixels(pix5, &countxor, tab);
1440  LEPT_FREE(tab);
1441  *pdiffxor = (l_float32)countxor / (l_float32)(count3 + count4);
1442 
1443  if (ppixdb) {
1444  pixa = pixaCreate(2);
1445  pix1 = pixCreate(w, h, 32);
1446  pixSetAll(pix1);
1447  pixRenderHashBoxaBlend(pix1, boxa3, 5, 1, L_POS_SLOPE_LINE, 2,
1448  255, 0, 0, 0.5);
1449  pixRenderHashBoxaBlend(pix1, boxa4, 5, 1, L_NEG_SLOPE_LINE, 2,
1450  0, 255, 0, 0.5);
1451  pixaAddPix(pixa, pix1, L_INSERT);
1452  pix2 = pixCreate(w, h, 32);
1453  pixPaintThroughMask(pix2, pix3, x3, y3, 0xff000000);
1454  pixPaintThroughMask(pix2, pix4, x4, y4, 0x00ff0000);
1455  pixAnd(pix3, pix3, pix4);
1456  pixPaintThroughMask(pix2, pix3, x3, y3, 0x0000ff00);
1457  pixaAddPix(pixa, pix2, L_INSERT);
1458  *ppixdb = pixaDisplayTiledInRows(pixa, 32, 1000, 1.0, 0, 30, 2);
1459  pixaDestroy(&pixa);
1460  }
1461 
1462  boxDestroy(&box3);
1463  boxDestroy(&box4);
1464  boxaDestroy(&boxa3);
1465  boxaDestroy(&boxa3t);
1466  boxaDestroy(&boxa4);
1467  boxaDestroy(&boxa4t);
1468  pixDestroy(&pix3);
1469  pixDestroy(&pix4);
1470  pixDestroy(&pix5);
1471  return 0;
1472 }
1473 
1474 
1475 /*---------------------------------------------------------------------*
1476  * Reliable selection of a single large box *
1477  *---------------------------------------------------------------------*/
1503 BOX *
1505  l_float32 areaslop,
1506  l_int32 yslop,
1507  l_int32 connectivity)
1508 {
1509 BOX *box;
1510 BOXA *boxa1;
1511 
1512  if (!pixs)
1513  return (BOX *)ERROR_PTR("pixs not defined", __func__, NULL);
1514  if (areaslop < 0.0 || areaslop > 1.0)
1515  return (BOX *)ERROR_PTR("invalid value for areaslop", __func__, NULL);
1516  yslop = L_MAX(0, yslop);
1517 
1518  boxa1 = pixConnCompBB(pixs, connectivity);
1519  if (boxaGetCount(boxa1) == 0) {
1520  boxaDestroy(&boxa1);
1521  return NULL;
1522  }
1523  box = boxaSelectLargeULBox(boxa1, areaslop, yslop);
1524  boxaDestroy(&boxa1);
1525  return box;
1526 }
1527 
1528 
1542 BOX *
1544  l_float32 areaslop,
1545  l_int32 yslop)
1546 {
1547 l_int32 w, h, i, n, x1, y1, x2, y2, select;
1548 l_float32 area, max_area;
1549 BOX *box;
1550 BOXA *boxa1, *boxa2, *boxa3;
1551 
1552  if (!boxas)
1553  return (BOX *)ERROR_PTR("boxas not defined", __func__, NULL);
1554  if (boxaGetCount(boxas) == 0)
1555  return (BOX *)ERROR_PTR("no boxes in boxas", __func__, NULL);
1556  if (areaslop < 0.0 || areaslop > 1.0)
1557  return (BOX *)ERROR_PTR("invalid value for areaslop", __func__, NULL);
1558  yslop = L_MAX(0, yslop);
1559 
1560  boxa1 = boxaSort(boxas, L_SORT_BY_AREA, L_SORT_DECREASING, NULL);
1561  boxa2 = boxaSort(boxa1, L_SORT_BY_Y, L_SORT_INCREASING, NULL);
1562  n = boxaGetCount(boxa2);
1563  boxaGetBoxGeometry(boxa1, 0, NULL, NULL, &w, &h); /* biggest box by area */
1564  max_area = (l_float32)(w * h);
1565 
1566  /* boxa3 collects all boxes eligible by area, sorted top-down */
1567  boxa3 = boxaCreate(4);
1568  for (i = 0; i < n; i++) {
1569  boxaGetBoxGeometry(boxa2, i, NULL, NULL, &w, &h);
1570  area = (l_float32)(w * h);
1571  if (area / max_area >= areaslop) {
1572  box = boxaGetBox(boxa2, i, L_COPY);
1573  boxaAddBox(boxa3, box, L_INSERT);
1574  }
1575  }
1576 
1577  /* Take the first (top-most box) unless the second (etc) has
1578  * nearly the same y value but a smaller x value. */
1579  n = boxaGetCount(boxa3);
1580  boxaGetBoxGeometry(boxa3, 0, &x1, &y1, NULL, NULL);
1581  select = 0;
1582  for (i = 1; i < n; i++) {
1583  boxaGetBoxGeometry(boxa3, i, &x2, &y2, NULL, NULL);
1584  if (y2 - y1 < yslop && x2 < x1) {
1585  select = i;
1586  x1 = x2; /* but always compare against y1 */
1587  }
1588  }
1589 
1590  box = boxaGetBox(boxa3, select, L_COPY);
1591  boxaDestroy(&boxa1);
1592  boxaDestroy(&boxa2);
1593  boxaDestroy(&boxa3);
1594  return box;
1595 }
#define GET_DATA_BIT(pdata, n)
Definition: arrayaccess.h:123
l_ok boxGetGeometry(const BOX *box, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxGetGeometry()
Definition: boxbasic.c:301
void boxDestroy(BOX **pbox)
boxDestroy()
Definition: boxbasic.c:273
l_int32 boxaaGetCount(BOXAA *baa)
boxaaGetCount()
Definition: boxbasic.c:1343
l_ok boxaGetBoxGeometry(BOXA *boxa, l_int32 index, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxaGetBoxGeometry()
Definition: boxbasic.c:796
l_ok boxaWriteStderr(BOXA *boxa)
boxaWriteStderr()
Definition: boxbasic.c:2176
l_ok boxaAddBox(BOXA *boxa, BOX *box, l_int32 copyflag)
boxaAddBox()
Definition: boxbasic.c:553
void boxaDestroy(BOXA **pboxa)
boxaDestroy()
Definition: boxbasic.c:519
l_int32 boxaGetCount(const BOXA *boxa)
boxaGetCount()
Definition: boxbasic.c:661
BOXA * boxaaGetBoxa(BOXAA *baa, l_int32 index, l_int32 accessflag)
boxaaGetBoxa()
Definition: boxbasic.c:1386
BOX * boxaGetBox(BOXA *boxa, l_int32 index, l_int32 accessflag)
boxaGetBox()
Definition: boxbasic.c:702
BOX * boxCreate(l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxCreate()
Definition: boxbasic.c:171
BOXA * boxaCreate(l_int32 n)
boxaCreate()
Definition: boxbasic.c:442
l_ok boxPrintStreamInfo(FILE *fp, BOX *box)
boxPrintStreamInfo()
Definition: boxbasic.c:2270
l_ok boxaJoin(BOXA *boxad, BOXA *boxas, l_int32 istart, l_int32 iend)
boxaJoin()
Definition: boxfunc1.c:2460
l_ok boxaaGetExtent(BOXAA *baa, l_int32 *pw, l_int32 *ph, BOX **pbox, BOXA **pboxa)
boxaaGetExtent()
Definition: boxfunc2.c:1531
BOX * boxTransform(BOX *box, l_int32 shiftx, l_int32 shifty, l_float32 scalex, l_float32 scaley)
boxTransform()
Definition: boxfunc2.c:151
BOXA * boxaTransform(BOXA *boxas, l_int32 shiftx, l_int32 shifty, l_float32 scalex, l_float32 scaley)
boxaTransform()
Definition: boxfunc2.c:103
BOXA * boxaSort(BOXA *boxas, l_int32 sorttype, l_int32 sortorder, NUMA **pnaindex)
boxaSort()
Definition: boxfunc2.c:624
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:818
PIX * pixPaintBoxa(PIX *pixs, BOXA *boxa, l_uint32 val)
pixPaintBoxa()
Definition: boxfunc3.c:216
PIX * pixSetBlackOrWhiteBoxa(PIX *pixs, BOXA *boxa, l_int32 op)
pixSetBlackOrWhiteBoxa()
Definition: boxfunc3.c:280
BOX * boxaSelectLargeULBox(BOXA *boxas, l_float32 areaslop, l_int32 yslop)
boxaSelectLargeULBox()
Definition: boxfunc3.c:1543
PIX * pixMaskBoxa(PIX *pixd, PIX *pixs, BOXA *boxa, l_int32 op)
pixMaskBoxa()
Definition: boxfunc3.c:149
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:621
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:925
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:1362
BOX * pixSelectLargeULComp(PIX *pixs, l_float32 areaslop, l_int32 yslop, l_int32 connectivity)
pixSelectLargeULComp()
Definition: boxfunc3.c:1504
BOXA * makeMosaicStrips(l_int32 w, l_int32 h, l_int32 direction, l_int32 size)
makeMosaicStrips()
Definition: boxfunc3.c:1285
PIXA * pixaDisplayBoxaa(PIXA *pixas, BOXAA *baa, l_int32 colorflag, l_int32 width)
pixaDisplayBoxaa()
Definition: boxfunc3.c:701
PIX * pixDrawBoxa(PIX *pixs, BOXA *boxa, l_int32 width, l_uint32 val)
pixDrawBoxa()
Definition: boxfunc3.c:487
PIX * pixDrawBoxaRandom(PIX *pixs, BOXA *boxa, l_int32 width)
pixDrawBoxaRandom()
Definition: boxfunc3.c:549
PIX * pixBlendBoxaRandom(PIX *pixs, BOXA *boxa, l_float32 fract)
pixBlendBoxaRandom()
Definition: boxfunc3.c:428
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:1038
PIX * pixPaintBoxaRandom(PIX *pixs, BOXA *boxa)
pixPaintBoxaRandom()
Definition: boxfunc3.c:359
BOXA * boxaSelectByArea(BOXA *boxas, l_int32 area, l_int32 relation, l_int32 *pchanged)
boxaSelectByArea()
Definition: boxfunc4.c:363
l_ok boxaGetArea(BOXA *boxa, l_int32 *parea)
boxaGetArea()
Definition: boxfunc4.c:1244
l_ok boxaGetExtent(BOXA *boxa, l_int32 *pw, l_int32 *ph, BOX **pbox)
boxaGetExtent()
Definition: boxfunc4.c:922
void pixcmapDestroy(PIXCMAP **pcmap)
pixcmapDestroy()
Definition: colormap.c:272
PIXCMAP * pixcmapCreateRandom(l_int32 depth, l_int32 hasblack, l_int32 haswhite)
pixcmapCreateRandom()
Definition: colormap.c:171
l_int32 pixcmapGetCount(const PIXCMAP *cmap)
pixcmapGetCount()
Definition: colormap.c:683
PIXCMAP * pixcmapCreate(l_int32 depth)
pixcmapCreate()
Definition: colormap.c:126
l_ok pixcmapAddNewColor(PIXCMAP *cmap, l_int32 rval, l_int32 gval, l_int32 bval, l_int32 *pindex)
pixcmapAddNewColor()
Definition: colormap.c:481
l_ok pixcmapAddBlackOrWhite(PIXCMAP *cmap, l_int32 color, l_int32 *pindex)
pixcmapAddBlackOrWhite()
Definition: colormap.c:618
l_ok pixcmapGetColor(PIXCMAP *cmap, l_int32 index, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
pixcmapGetColor()
Definition: colormap.c:789
l_ok pixcmapAddColor(PIXCMAP *cmap, l_int32 rval, l_int32 gval, l_int32 bval)
pixcmapAddColor()
Definition: colormap.c:403
BOXA * pixConnCompBB(PIX *pixs, l_int32 connectivity)
pixConnCompBB()
Definition: conncomp.c:307
BOXA * pixConnComp(PIX *pixs, PIXA **ppixa, l_int32 connectivity)
pixConnComp()
Definition: conncomp.c:152
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:2123
PIX * pixRenderRandomCmapPtaa(PIX *pix, PTAA *ptaa, l_int32 polyflag, l_int32 width, l_int32 closeflag)
pixRenderRandomCmapPtaa()
Definition: graphics.c:2356
PTAA * generatePtaaBoxa(BOXA *boxa)
generatePtaaBoxa()
Definition: graphics.c:561
l_ok pixRenderBoxArb(PIX *pix, BOX *box, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval)
pixRenderBoxArb()
Definition: graphics.c:1606
l_ok pixRenderBoxaArb(PIX *pix, BOXA *boxa, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval)
pixRenderBoxaArb()
Definition: graphics.c:1717
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:460
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:193
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:357
l_ok numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition: numabasic.c:720
NUMA * numaGetSortIndex(NUMA *na, l_int32 sortorder)
numaGetSortIndex()
Definition: numafunc1.c:2664
l_ok pixSetColormap(PIX *pix, PIXCMAP *colormap)
pixSetColormap()
Definition: pix1.c:1582
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:608
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1074
PIX * pixCopy(PIX *pixd, const PIX *pixs)
pixCopy()
Definition: pix1.c:689
PIX * pixCreateTemplate(const PIX *pixs)
pixCreateTemplate()
Definition: pix1.c:380
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:315
void ** pixGetLinePtrs(PIX *pix, l_int32 *psize)
pixGetLinePtrs()
Definition: pix1.c:1844
l_ok pixSetInRectArbitrary(PIX *pix, BOX *box, l_uint32 val)
pixSetInRectArbitrary()
Definition: pix2.c:1163
l_ok pixClearInRect(PIX *pix, BOX *box)
pixClearInRect()
Definition: pix2.c:1090
l_ok pixSetInRect(PIX *pix, BOX *box)
pixSetInRect()
Definition: pix2.c:1123
l_ok pixSetAll(PIX *pix)
pixSetAll()
Definition: pix2.c:799
l_ok pixBlendInRect(PIX *pixs, BOX *box, l_uint32 val, l_float32 fract)
pixBlendInRect()
Definition: pix2.c:1262
l_ok composeRGBPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_uint32 *ppixel)
composeRGBPixel()
Definition: pix2.c:2728
void extractRGBValues(l_uint32 pixel, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
extractRGBValues()
Definition: pix2.c:2793
l_ok pixPaintThroughMask(PIX *pixd, PIX *pixm, l_int32 x, l_int32 y, l_uint32 val)
pixPaintThroughMask()
Definition: pix3.c:618
l_ok pixCountPixels(PIX *pixs, l_int32 *pcount, l_int32 *tab8)
pixCountPixels()
Definition: pix3.c:1893
PIX * pixAnd(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixAnd()
Definition: pix3.c:1592
l_int32 * makePixelSumTab8(void)
makePixelSumTab8()
Definition: pix3.c:2354
PIX * pixXor(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixXor()
Definition: pix3.c:1654
l_ok pixClipBoxToForeground(PIX *pixs, BOX *boxs, PIX **ppixd, BOX **pboxd)
pixClipBoxToForeground()
Definition: pix5.c:1896
@ L_DRAW_RANDOM
Definition: pix.h:354
@ L_DRAW_RED
Definition: pix.h:349
@ L_DRAW_RGB
Definition: pix.h:353
@ L_DRAW_BLUE
Definition: pix.h:351
@ L_DRAW_GREEN
Definition: pix.h:350
#define PIX_DST
Definition: pix.h:445
@ L_FLIP_PIXELS
Definition: pix.h:567
@ L_SET_PIXELS
Definition: pix.h:565
@ L_CLEAR_PIXELS
Definition: pix.h:566
@ L_SELECT_IF_GTE
Definition: pix.h:578
@ L_POS_SLOPE_LINE
Definition: pix.h:807
@ L_NEG_SLOPE_LINE
Definition: pix.h:809
@ L_SORT_BY_AREA
Definition: pix.h:537
@ L_SORT_BY_Y
Definition: pix.h:529
@ L_COPY
Definition: pix.h:505
@ L_CLONE
Definition: pix.h:506
@ L_INSERT
Definition: pix.h:504
@ L_SET_WHITE
Definition: pix.h:699
@ L_FROM_BOT
Definition: pix.h:830
@ L_FROM_LEFT
Definition: pix.h:827
@ L_SCAN_VERTICAL
Definition: pix.h:835
@ L_SCAN_HORIZONTAL
Definition: pix.h:834
@ L_FROM_RIGHT
Definition: pix.h:828
@ L_FROM_TOP
Definition: pix.h:829
#define PIX_CLR
Definition: pix.h:447
@ L_SORT_DECREASING
Definition: pix.h:523
@ L_SORT_INCREASING
Definition: pix.h:522
#define PIX_NOT(op)
Definition: pix.h:446
#define PIX_SET
Definition: pix.h:448
l_ok pixaAddPix(PIXA *pixa, PIX *pix, l_int32 copyflag)
pixaAddPix()
Definition: pixabasic.c:493
void pixaDestroy(PIXA **ppixa)
pixaDestroy()
Definition: pixabasic.c:404
PIXA * pixaCreate(l_int32 n)
pixaCreate()
Definition: pixabasic.c:167
l_int32 pixaGetCount(PIXA *pixa)
pixaGetCount()
Definition: pixabasic.c:629
PIX * pixaGetPix(PIXA *pixa, l_int32 index, l_int32 accesstype)
pixaGetPix()
Definition: pixabasic.c:647
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:730
PIX * pixConvert1To8(PIX *pixd, PIX *pixs, l_uint8 val0, l_uint8 val1)
pixConvert1To8()
Definition: pixconv.c:2345
PIX * pixConvertTo8(PIX *pixs, l_int32 cmapflag)
pixConvertTo8()
Definition: pixconv.c:3055
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3246
void ptaaDestroy(PTAA **pptaa)
ptaaDestroy()
Definition: ptabasic.c:930
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
void lept_stderr(const char *fmt,...)
lept_stderr()
Definition: utils1.c:306