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