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 
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  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 
150 PIX *
152  PIX *pixs,
153  BOXA *boxa,
154  l_int32 op)
155 {
156 l_int32 i, n, x, y, w, h;
157 BOX *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 
219 PIX *
221  BOXA *boxa,
222  l_uint32 val)
223 {
224 l_int32 i, n, d, rval, gval, bval, newindex;
225 l_int32 mapvacancy; /* true only if cmap and not full */
226 BOX *box;
227 PIX *pixd;
228 PIXCMAP *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 
285 PIX *
287  BOXA *boxa,
288  l_int32 op)
289 {
290 l_int32 i, n, d, index;
291 l_uint32 color;
292 BOX *box;
293 PIX *pixd;
294 PIXCMAP *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 
366 PIX *
368  BOXA *boxa)
369 {
370 l_int32 i, n, d, rval, gval, bval, index;
371 l_uint32 val;
372 BOX *box;
373 PIX *pixd;
374 PIXCMAP *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 
437 PIX *
439  BOXA *boxa,
440  l_float32 fract)
441 {
442 l_int32 i, n, rval, gval, bval, index;
443 l_uint32 val;
444 BOX *box;
445 PIX *pixd;
446 PIXCMAP *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 
498 PIX *
500  BOXA *boxa,
501  l_int32 width,
502  l_uint32 val)
503 {
504 l_int32 rval, gval, bval, newindex;
505 l_int32 mapvacancy; /* true only if cmap and not full */
506 PIX *pixd;
507 PIXCMAP *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 
562 PIX *
564  BOXA *boxa,
565  l_int32 width)
566 {
567 l_int32 i, n, rval, gval, bval, index;
568 BOX *box;
569 PIX *pixd;
570 PIXCMAP *cmap;
571 PTAA *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 
636 PIX *
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 {
646 l_int32 i, j, n, m, rbox, gbox, bbox, rboxa, gboxa, bboxa;
647 BOX *box;
648 BOXA *boxa;
649 PIX *pixd;
650 PIXCMAP *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 
718 PIXA *
720  BOXAA *baa,
721  l_int32 colorflag,
722  l_int32 width)
723 {
724 l_int32 i, j, nba, n, nbox, rval, gval, bval;
725 l_uint32 color;
726 l_uint32 colors[255];
727 BOXA *boxa;
728 BOX *box;
729 PIX *pix;
730 PIXA *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  *---------------------------------------------------------------------*/
837 BOXA *
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 {
846 l_int32 i, n;
847 BOX *box;
848 BOXA *boxa, *boxas, *boxad;
849 PIX *pix;
850 PIXA *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 
946 BOXA *
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 {
956 l_int32 i, w, h, boxx, boxy, bx, by, bw, bh, maxdir, maxscore;
957 l_int32 iter;
958 BOX *boxs; /* shrinks as rectangular regions are removed */
959 BOX *boxt1, *boxt2, *boxt3;
960 BOXA *boxat; /* stores rectangle data for each side in an iteration */
961 BOXA *boxad;
962 NUMA *nascore, *nas;
963 PIX *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 
1061 static 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 {
1072 l_int32 bx, by, bw, bh, width, height, setref, atref;
1073 l_int32 minincol, maxincol, mininrow, maxinrow, minval, maxval, bgref;
1074 l_int32 x, y, x0, y0, xref, yref, colsum, rowsum, score, countref, diff;
1075 void **lines1;
1076 BOX *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 
1274 failure:
1275  numaAddNumber(nascore, 0);
1276  boxaAddBox(boxat, boxCreate(0, 0, 1, 1), L_INSERT); /* min box */
1277  LEPT_FREE(lines1);
1278  return 0;
1279 
1280 success:
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  *---------------------------------------------------------------------*/
1310 BOXA *
1312  l_int32 h,
1313  l_int32 direction,
1314  l_int32 size)
1315 {
1316 l_int32 i, nstrips, extra;
1317 BOX *box;
1318 BOXA *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  *---------------------------------------------------------------------*/
1389 l_ok
1391  BOXA *boxa2,
1392  l_int32 areathresh,
1393  l_int32 *pnsame,
1394  l_float32 *pdiffarea,
1395  l_float32 *pdiffxor,
1396  PIX **ppixdb)
1397 {
1398 l_int32 w, h, x3, y3, w3, h3, x4, y4, w4, h4, n3, n4, area1, area2;
1399 l_int32 count3, count4, countxor;
1400 l_int32 *tab;
1401 BOX *box3, *box4;
1402 BOXA *boxa3, *boxa4, *boxa3t, *boxa4t;
1403 PIX *pix1, *pix2, *pix3, *pix4, *pix5;
1404 PIXA *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  *---------------------------------------------------------------------*/
1533 BOX *
1535  l_float32 areaslop,
1536  l_int32 yslop,
1537  l_int32 connectivity)
1538 {
1539 BOX *box;
1540 BOXA *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 
1574 BOX *
1576  l_float32 areaslop,
1577  l_int32 yslop)
1578 {
1579 l_int32 w, h, i, n, x1, y1, x2, y2, select;
1580 l_float32 area, max_area;
1581 BOX *box;
1582 BOXA *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
void boxDestroy(BOX **pbox)
boxDestroy()
Definition: boxbasic.c:282
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
l_ok boxaAddBox(BOXA *boxa, BOX *box, l_int32 copyflag)
boxaAddBox()
Definition: boxbasic.c:620
void boxaDestroy(BOXA **pboxa)
boxaDestroy()
Definition: boxbasic.c:583
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
BOX * boxCreate(l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxCreate()
Definition: boxbasic.c:172
BOXA * boxaCreate(l_int32 n)
boxaCreate()
Definition: boxbasic.c:502
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
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
PIX * pixPaintBoxa(PIX *pixs, BOXA *boxa, l_uint32 val)
pixPaintBoxa()
Definition: boxfunc3.c:220
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
PIX * pixMaskBoxa(PIX *pixd, PIX *pixs, BOXA *boxa, l_int32 op)
pixMaskBoxa()
Definition: boxfunc3.c:151
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
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
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
BOX * pixSelectLargeULComp(PIX *pixs, l_float32 areaslop, l_int32 yslop, l_int32 connectivity)
pixSelectLargeULComp()
Definition: boxfunc3.c:1534
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 * pixDrawBoxa(PIX *pixs, BOXA *boxa, l_int32 width, l_uint32 val)
pixDrawBoxa()
Definition: boxfunc3.c:499
PIX * pixDrawBoxaRandom(PIX *pixs, BOXA *boxa, l_int32 width)
pixDrawBoxaRandom()
Definition: boxfunc3.c:563
PIX * pixBlendBoxaRandom(PIX *pixs, BOXA *boxa, l_float32 fract)
pixBlendBoxaRandom()
Definition: boxfunc3.c:438
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
PIX * pixPaintBoxaRandom(PIX *pixs, BOXA *boxa)
pixPaintBoxaRandom()
Definition: boxfunc3.c:367
BOXA * boxaSelectByArea(BOXA *boxas, l_int32 area, l_int32 relation, l_int32 *pchanged)
boxaSelectByArea()
Definition: boxfunc4.c:370
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
void pixcmapDestroy(PIXCMAP **pcmap)
pixcmapDestroy()
Definition: colormap.c:279
PIXCMAP * pixcmapCreateRandom(l_int32 depth, l_int32 hasblack, l_int32 haswhite)
pixcmapCreateRandom()
Definition: colormap.c:172
l_int32 pixcmapGetCount(const PIXCMAP *cmap)
pixcmapGetCount()
Definition: colormap.c:708
PIXCMAP * pixcmapCreate(l_int32 depth)
pixcmapCreate()
Definition: colormap.c:125
l_ok pixcmapAddNewColor(PIXCMAP *cmap, l_int32 rval, l_int32 gval, l_int32 bval, l_int32 *pindex)
pixcmapAddNewColor()
Definition: colormap.c:496
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 * pixConnCompBB(PIX *pixs, l_int32 connectivity)
pixConnCompBB()
Definition: conncomp.c:310
BOXA * pixConnComp(PIX *pixs, PIXA **ppixa, l_int32 connectivity)
pixConnComp()
Definition: conncomp.c:151
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
PIX * pixRenderRandomCmapPtaa(PIX *pix, PTAA *ptaa, l_int32 polyflag, l_int32 width, l_int32 closeflag)
pixRenderRandomCmapPtaa()
Definition: graphics.c:2437
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
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:478
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:194
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 * numaGetSortIndex(NUMA *na, l_int32 sortorder)
numaGetSortIndex()
Definition: numafunc1.c:2751
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 * pixCopy(PIX *pixd, const PIX *pixs)
pixCopy()
Definition: pix1.c:705
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
void ** pixGetLinePtrs(PIX *pix, l_int32 *psize)
pixGetLinePtrs()
Definition: pix1.c:1949
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_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
l_int32 * makePixelSumTab8(void)
makePixelSumTab8()
Definition: pix3.c:2411
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 * pixConvert1To8(PIX *pixd, PIX *pixs, l_uint8 val0, l_uint8 val1)
pixConvert1To8()
Definition: pixconv.c:2401
PIX * pixConvertTo8(PIX *pixs, l_int32 cmapflag)
pixConvertTo8()
Definition: pixconv.c:3133
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3332
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