Leptonica  1.82.0
Image processing and image analysis suite
pixafunc1.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 
95 #ifdef HAVE_CONFIG_H
96 #include <config_auto.h>
97 #endif /* HAVE_CONFIG_H */
98 
99 #include <string.h>
100 #include "allheaders.h"
101 
102  /* For more than this number of c.c. in a binarized image of
103  * semi-perimeter (w + h) about 5000 or less, the O(n) binsort
104  * is faster than the O(nlogn) shellsort. */
105 static const l_int32 MinCompsForBinSort = 200;
106 
107  /* Don't rotate any angle smaller than this */
108 static const l_float32 MinAngleToRotate = 0.001; /* radians; ~0.06 deg */
109 
110 /*---------------------------------------------------------------------*
111  * Filters *
112  *---------------------------------------------------------------------*/
113 /*
114  * These filters work on the connected components of 1 bpp images.
115  * They are typically used on pixa that have been generated from a Pix
116  * using pixConnComp(), so that the corresponding Boxa is available.
117  *
118  * The filters remove or retain c.c. based on these properties:
119  * (a) size [pixaFindDimensions()]
120  * (b) area-to-perimeter ratio [pixaFindAreaPerimRatio()]
121  * (c) foreground area as a fraction of bounding box area (w * h)
122  * [pixaFindForegroundArea()]
123  * (d) number of foreground pixels [pixaCountPixels()]
124  * (e) width/height aspect ratio [pixFindWidthHeightRatio()]
125  *
126  * We provide two different high-level interfaces:
127  * (1) Functions that use one of the filters on either
128  * a pix or the pixa of components.
129  * (2) A general method that generates numas of indicator functions,
130  * logically combines them, and efficiently removes or adds
131  * the selected components.
132  *
133  * For interface (1), the filtering is performed with a single function call.
134  * This is the easiest way to do simple filtering. These functions
135  * are named pixSelectBy*() and pixaSelectBy*(), where the '*' is one of:
136  * Size
137  * PerimToAreaRatio
138  * PerimSizeRatio
139  * Area
140  * AreaFraction
141  * WidthHeightRatio
142  *
143  * For more complicated filtering, use the general method (2).
144  * The numa indicator functions for a pixa are generated by these functions:
145  * pixaFindDimensions()
146  * pixaFindPerimToAreaRatio()
147  * pixaFindPerimSizeRatio()
148  * pixaFindAreaFraction()
149  * pixaCountPixels()
150  * pixaFindWidthHeightRatio()
151  * pixaFindWidthHeightProduct()
152  *
153  * Here is an illustration using the general method. Suppose you want
154  * all 8-connected components that have a height greater than 40 pixels,
155  * a width not more than 30 pixels, between 150 and 300 fg pixels,
156  * and a perimeter-to-size ratio between 1.2 and 2.0.
157  *
158  * // Generate the pixa of 8 cc pieces.
159  * boxa = pixConnComp(pixs, &pixa, 8);
160  *
161  * // Extract the data we need about each component.
162  * pixaFindDimensions(pixa, &naw, &nah);
163  * nas = pixaCountPixels(pixa);
164  * nar = pixaFindPerimSizeRatio(pixa);
165  *
166  * // Build the indicator arrays for the set of components,
167  * // based on thresholds and selection criteria.
168  * na1 = numaMakeThresholdIndicator(nah, 40, L_SELECT_IF_GT);
169  * na2 = numaMakeThresholdIndicator(naw, 30, L_SELECT_IF_LTE);
170  * na3 = numaMakeThresholdIndicator(nas, 150, L_SELECT_IF_GTE);
171  * na4 = numaMakeThresholdIndicator(nas, 300, L_SELECT_IF_LTE);
172  * na5 = numaMakeThresholdIndicator(nar, 1.2, L_SELECT_IF_GTE);
173  * na6 = numaMakeThresholdIndicator(nar, 2.0, L_SELECT_IF_LTE);
174  *
175  * // Combine the indicator arrays logically to find
176  * // the components that will be retained.
177  * nad = numaLogicalOp(NULL, na1, na2, L_INTERSECTION);
178  * numaLogicalOp(nad, nad, na3, L_INTERSECTION);
179  * numaLogicalOp(nad, nad, na4, L_INTERSECTION);
180  * numaLogicalOp(nad, nad, na5, L_INTERSECTION);
181  * numaLogicalOp(nad, nad, na6, L_INTERSECTION);
182  *
183  * // Invert to get the components that will be removed.
184  * numaInvert(nad, nad);
185  *
186  * // Remove the components, in-place.
187  * pixRemoveWithIndicator(pixs, pixa, nad);
188  */
189 
190 
218 PIX *
220  l_int32 width,
221  l_int32 height,
222  l_int32 connectivity,
223  l_int32 type,
224  l_int32 relation,
225  l_int32 *pchanged)
226 {
227 l_int32 w, h, empty, changed, count;
228 BOXA *boxa;
229 PIX *pixd;
230 PIXA *pixas, *pixad;
231 
232  PROCNAME("pixSelectBySize");
233 
234  if (!pixs)
235  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
236  if (connectivity != 4 && connectivity != 8)
237  return (PIX *)ERROR_PTR("connectivity not 4 or 8", procName, NULL);
238  if (type != L_SELECT_WIDTH && type != L_SELECT_HEIGHT &&
239  type != L_SELECT_IF_EITHER && type != L_SELECT_IF_BOTH)
240  return (PIX *)ERROR_PTR("invalid type", procName, NULL);
241  if (relation != L_SELECT_IF_LT && relation != L_SELECT_IF_GT &&
242  relation != L_SELECT_IF_LTE && relation != L_SELECT_IF_GTE)
243  return (PIX *)ERROR_PTR("invalid relation", procName, NULL);
244  if (pchanged) *pchanged = FALSE;
245 
246  /* Check if any components exist */
247  pixZero(pixs, &empty);
248  if (empty)
249  return pixCopy(NULL, pixs);
250 
251  /* Identify and select the components */
252  boxa = pixConnComp(pixs, &pixas, connectivity);
253  pixad = pixaSelectBySize(pixas, width, height, type, relation, &changed);
254  boxaDestroy(&boxa);
255  pixaDestroy(&pixas);
256 
257  if (!changed) {
258  pixaDestroy(&pixad);
259  return pixCopy(NULL, pixs);
260  }
261 
262  /* Render the result */
263  if (pchanged) *pchanged = TRUE;
264  pixGetDimensions(pixs, &w, &h, NULL);
265  count = pixaGetCount(pixad);
266  if (count == 0) { /* return empty pix */
267  pixd = pixCreateTemplate(pixs);
268  } else {
269  pixd = pixaDisplay(pixad, w, h);
270  pixCopyResolution(pixd, pixs);
271  pixCopyColormap(pixd, pixs);
272  pixCopyText(pixd, pixs);
273  pixCopyInputFormat(pixd, pixs);
274  }
275  pixaDestroy(&pixad);
276  return pixd;
277 }
278 
279 
305 PIXA *
307  l_int32 width,
308  l_int32 height,
309  l_int32 type,
310  l_int32 relation,
311  l_int32 *pchanged)
312 {
313 NUMA *na;
314 PIXA *pixad;
315 
316  PROCNAME("pixaSelectBySize");
317 
318  if (!pixas)
319  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
320  if (type != L_SELECT_WIDTH && type != L_SELECT_HEIGHT &&
321  type != L_SELECT_IF_EITHER && type != L_SELECT_IF_BOTH)
322  return (PIXA *)ERROR_PTR("invalid type", procName, NULL);
323  if (relation != L_SELECT_IF_LT && relation != L_SELECT_IF_GT &&
324  relation != L_SELECT_IF_LTE && relation != L_SELECT_IF_GTE)
325  return (PIXA *)ERROR_PTR("invalid relation", procName, NULL);
326 
327  /* Compute the indicator array for saving components */
328  na = pixaMakeSizeIndicator(pixas, width, height, type, relation);
329 
330  /* Filter to get output */
331  pixad = pixaSelectWithIndicator(pixas, na, pchanged);
332 
333  numaDestroy(&na);
334  return pixad;
335 }
336 
337 
361 NUMA *
363  l_int32 width,
364  l_int32 height,
365  l_int32 type,
366  l_int32 relation)
367 {
368 l_int32 i, n, w, h, ival;
369 NUMA *na;
370 
371  PROCNAME("pixaMakeSizeIndicator");
372 
373  if (!pixa)
374  return (NUMA *)ERROR_PTR("pixa not defined", procName, NULL);
375  if (type != L_SELECT_WIDTH && type != L_SELECT_HEIGHT &&
376  type != L_SELECT_IF_EITHER && type != L_SELECT_IF_BOTH)
377  return (NUMA *)ERROR_PTR("invalid type", procName, NULL);
378  if (relation != L_SELECT_IF_LT && relation != L_SELECT_IF_GT &&
379  relation != L_SELECT_IF_LTE && relation != L_SELECT_IF_GTE)
380  return (NUMA *)ERROR_PTR("invalid relation", procName, NULL);
381 
382  n = pixaGetCount(pixa);
383  na = numaCreate(n);
384  for (i = 0; i < n; i++) {
385  ival = 0;
386  pixaGetPixDimensions(pixa, i, &w, &h, NULL);
387  switch (type)
388  {
389  case L_SELECT_WIDTH:
390  if ((relation == L_SELECT_IF_LT && w < width) ||
391  (relation == L_SELECT_IF_GT && w > width) ||
392  (relation == L_SELECT_IF_LTE && w <= width) ||
393  (relation == L_SELECT_IF_GTE && w >= width))
394  ival = 1;
395  break;
396  case L_SELECT_HEIGHT:
397  if ((relation == L_SELECT_IF_LT && h < height) ||
398  (relation == L_SELECT_IF_GT && h > height) ||
399  (relation == L_SELECT_IF_LTE && h <= height) ||
400  (relation == L_SELECT_IF_GTE && h >= height))
401  ival = 1;
402  break;
403  case L_SELECT_IF_EITHER:
404  if (((relation == L_SELECT_IF_LT) && (w < width || h < height)) ||
405  ((relation == L_SELECT_IF_GT) && (w > width || h > height)) ||
406  ((relation == L_SELECT_IF_LTE) && (w <= width || h <= height)) ||
407  ((relation == L_SELECT_IF_GTE) && (w >= width || h >= height)))
408  ival = 1;
409  break;
410  case L_SELECT_IF_BOTH:
411  if (((relation == L_SELECT_IF_LT) && (w < width && h < height)) ||
412  ((relation == L_SELECT_IF_GT) && (w > width && h > height)) ||
413  ((relation == L_SELECT_IF_LTE) && (w <= width && h <= height)) ||
414  ((relation == L_SELECT_IF_GTE) && (w >= width && h >= height)))
415  ival = 1;
416  break;
417  default:
418  L_WARNING("can't get here!\n", procName);
419  break;
420  }
421  numaAddNumber(na, ival);
422  }
423 
424  return na;
425 }
426 
427 
452 PIX *
454  l_float32 thresh,
455  l_int32 connectivity,
456  l_int32 type,
457  l_int32 *pchanged)
458 {
459 l_int32 w, h, empty, changed, count;
460 BOXA *boxa;
461 PIX *pixd;
462 PIXA *pixas, *pixad;
463 
464  PROCNAME("pixSelectByPerimToAreaRatio");
465 
466  if (!pixs)
467  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
468  if (connectivity != 4 && connectivity != 8)
469  return (PIX *)ERROR_PTR("connectivity not 4 or 8", procName, NULL);
470  if (type != L_SELECT_IF_LT && type != L_SELECT_IF_GT &&
471  type != L_SELECT_IF_LTE && type != L_SELECT_IF_GTE)
472  return (PIX *)ERROR_PTR("invalid type", procName, NULL);
473  if (pchanged) *pchanged = FALSE;
474 
475  /* Check if any components exist */
476  pixZero(pixs, &empty);
477  if (empty)
478  return pixCopy(NULL, pixs);
479 
480  /* Filter thin components */
481  boxa = pixConnComp(pixs, &pixas, connectivity);
482  pixad = pixaSelectByPerimToAreaRatio(pixas, thresh, type, &changed);
483  boxaDestroy(&boxa);
484  pixaDestroy(&pixas);
485 
486  if (!changed) {
487  pixaDestroy(&pixad);
488  return pixCopy(NULL, pixs);
489  }
490 
491  /* Render the result */
492  if (pchanged) *pchanged = TRUE;
493  pixGetDimensions(pixs, &w, &h, NULL);
494  count = pixaGetCount(pixad);
495  if (count == 0) { /* return empty pix */
496  pixd = pixCreateTemplate(pixs);
497  } else {
498  pixd = pixaDisplay(pixad, w, h);
499  pixCopyResolution(pixd, pixs);
500  pixCopyColormap(pixd, pixs);
501  pixCopyText(pixd, pixs);
502  pixCopyInputFormat(pixd, pixs);
503  }
504  pixaDestroy(&pixad);
505  return pixd;
506 }
507 
508 
526 PIXA *
528  l_float32 thresh,
529  l_int32 type,
530  l_int32 *pchanged)
531 {
532 NUMA *na, *nai;
533 PIXA *pixad;
534 
535  PROCNAME("pixaSelectByPerimToAreaRatio");
536 
537  if (!pixas)
538  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
539  if (type != L_SELECT_IF_LT && type != L_SELECT_IF_GT &&
540  type != L_SELECT_IF_LTE && type != L_SELECT_IF_GTE)
541  return (PIXA *)ERROR_PTR("invalid type", procName, NULL);
542 
543  /* Compute component ratios. */
544  na = pixaFindPerimToAreaRatio(pixas);
545 
546  /* Generate indicator array for elements to be saved. */
547  nai = numaMakeThresholdIndicator(na, thresh, type);
548  numaDestroy(&na);
549 
550  /* Filter to get output */
551  pixad = pixaSelectWithIndicator(pixas, nai, pchanged);
552 
553  numaDestroy(&nai);
554  return pixad;
555 }
556 
557 
583 PIX *
585  l_float32 thresh,
586  l_int32 connectivity,
587  l_int32 type,
588  l_int32 *pchanged)
589 {
590 l_int32 w, h, empty, changed, count;
591 BOXA *boxa;
592 PIX *pixd;
593 PIXA *pixas, *pixad;
594 
595  PROCNAME("pixSelectByPerimSizeRatio");
596 
597  if (!pixs)
598  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
599  if (connectivity != 4 && connectivity != 8)
600  return (PIX *)ERROR_PTR("connectivity not 4 or 8", procName, NULL);
601  if (type != L_SELECT_IF_LT && type != L_SELECT_IF_GT &&
602  type != L_SELECT_IF_LTE && type != L_SELECT_IF_GTE)
603  return (PIX *)ERROR_PTR("invalid type", procName, NULL);
604  if (pchanged) *pchanged = FALSE;
605 
606  /* Check if any components exist */
607  pixZero(pixs, &empty);
608  if (empty)
609  return pixCopy(NULL, pixs);
610 
611  /* Filter thin components */
612  boxa = pixConnComp(pixs, &pixas, connectivity);
613  pixad = pixaSelectByPerimSizeRatio(pixas, thresh, type, &changed);
614  boxaDestroy(&boxa);
615  pixaDestroy(&pixas);
616 
617  if (!changed) {
618  pixaDestroy(&pixad);
619  return pixCopy(NULL, pixs);
620  }
621 
622  /* Render the result */
623  if (pchanged) *pchanged = TRUE;
624  pixGetDimensions(pixs, &w, &h, NULL);
625  count = pixaGetCount(pixad);
626  if (count == 0) { /* return empty pix */
627  pixd = pixCreateTemplate(pixs);
628  } else {
629  pixd = pixaDisplay(pixad, w, h);
630  pixCopyResolution(pixd, pixs);
631  pixCopyColormap(pixd, pixs);
632  pixCopyText(pixd, pixs);
633  pixCopyInputFormat(pixd, pixs);
634  }
635  pixaDestroy(&pixad);
636  return pixd;
637 }
638 
639 
657 PIXA *
659  l_float32 thresh,
660  l_int32 type,
661  l_int32 *pchanged)
662 {
663 NUMA *na, *nai;
664 PIXA *pixad;
665 
666  PROCNAME("pixaSelectByPerimSizeRatio");
667 
668  if (!pixas)
669  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
670  if (type != L_SELECT_IF_LT && type != L_SELECT_IF_GT &&
671  type != L_SELECT_IF_LTE && type != L_SELECT_IF_GTE)
672  return (PIXA *)ERROR_PTR("invalid type", procName, NULL);
673 
674  /* Compute component ratios. */
675  na = pixaFindPerimSizeRatio(pixas);
676 
677  /* Generate indicator array for elements to be saved. */
678  nai = numaMakeThresholdIndicator(na, thresh, type);
679  numaDestroy(&na);
680 
681  /* Filter to get output */
682  pixad = pixaSelectWithIndicator(pixas, nai, pchanged);
683 
684  numaDestroy(&nai);
685  return pixad;
686 }
687 
688 
713 PIX *
715  l_float32 thresh,
716  l_int32 connectivity,
717  l_int32 type,
718  l_int32 *pchanged)
719 {
720 l_int32 w, h, empty, changed, count;
721 BOXA *boxa;
722 PIX *pixd;
723 PIXA *pixas, *pixad;
724 
725  PROCNAME("pixSelectByAreaFraction");
726 
727  if (!pixs)
728  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
729  if (connectivity != 4 && connectivity != 8)
730  return (PIX *)ERROR_PTR("connectivity not 4 or 8", procName, NULL);
731  if (type != L_SELECT_IF_LT && type != L_SELECT_IF_GT &&
732  type != L_SELECT_IF_LTE && type != L_SELECT_IF_GTE)
733  return (PIX *)ERROR_PTR("invalid type", procName, NULL);
734  if (pchanged) *pchanged = FALSE;
735 
736  /* Check if any components exist */
737  pixZero(pixs, &empty);
738  if (empty)
739  return pixCopy(NULL, pixs);
740 
741  /* Filter components */
742  boxa = pixConnComp(pixs, &pixas, connectivity);
743  pixad = pixaSelectByAreaFraction(pixas, thresh, type, &changed);
744  boxaDestroy(&boxa);
745  pixaDestroy(&pixas);
746 
747  if (!changed) {
748  pixaDestroy(&pixad);
749  return pixCopy(NULL, pixs);
750  }
751 
752  /* Render the result */
753  if (pchanged) *pchanged = TRUE;
754  pixGetDimensions(pixs, &w, &h, NULL);
755  count = pixaGetCount(pixad);
756  if (count == 0) { /* return empty pix */
757  pixd = pixCreateTemplate(pixs);
758  } else {
759  pixd = pixaDisplay(pixad, w, h);
760  pixCopyResolution(pixd, pixs);
761  pixCopyColormap(pixd, pixs);
762  pixCopyText(pixd, pixs);
763  pixCopyInputFormat(pixd, pixs);
764  }
765  pixaDestroy(&pixad);
766  return pixd;
767 }
768 
769 
791 PIXA *
793  l_float32 thresh,
794  l_int32 type,
795  l_int32 *pchanged)
796 {
797 NUMA *na, *nai;
798 PIXA *pixad;
799 
800  PROCNAME("pixaSelectByAreaFraction");
801 
802  if (!pixas)
803  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
804  if (type != L_SELECT_IF_LT && type != L_SELECT_IF_GT &&
805  type != L_SELECT_IF_LTE && type != L_SELECT_IF_GTE)
806  return (PIXA *)ERROR_PTR("invalid type", procName, NULL);
807 
808  /* Compute component ratios. */
809  na = pixaFindAreaFraction(pixas);
810 
811  /* Generate indicator array for elements to be saved. */
812  nai = numaMakeThresholdIndicator(na, thresh, type);
813  numaDestroy(&na);
814 
815  /* Filter to get output */
816  pixad = pixaSelectWithIndicator(pixas, nai, pchanged);
817 
818  numaDestroy(&nai);
819  return pixad;
820 }
821 
822 
847 PIX *
849  l_float32 thresh,
850  l_int32 connectivity,
851  l_int32 type,
852  l_int32 *pchanged)
853 {
854 l_int32 w, h, empty, changed, count;
855 BOXA *boxa;
856 PIX *pixd;
857 PIXA *pixas, *pixad;
858 
859  PROCNAME("pixSelectByArea");
860 
861  if (!pixs)
862  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
863  if (connectivity != 4 && connectivity != 8)
864  return (PIX *)ERROR_PTR("connectivity not 4 or 8", procName, NULL);
865  if (type != L_SELECT_IF_LT && type != L_SELECT_IF_GT &&
866  type != L_SELECT_IF_LTE && type != L_SELECT_IF_GTE)
867  return (PIX *)ERROR_PTR("invalid type", procName, NULL);
868  if (pchanged) *pchanged = FALSE;
869 
870  /* Check if any components exist */
871  pixZero(pixs, &empty);
872  if (empty)
873  return pixCopy(NULL, pixs);
874 
875  /* Filter components */
876  boxa = pixConnComp(pixs, &pixas, connectivity);
877  pixad = pixaSelectByArea(pixas, thresh, type, &changed);
878  boxaDestroy(&boxa);
879  pixaDestroy(&pixas);
880 
881  if (!changed) {
882  pixaDestroy(&pixad);
883  return pixCopy(NULL, pixs);
884  }
885 
886  /* Render the result */
887  if (pchanged) *pchanged = TRUE;
888  pixGetDimensions(pixs, &w, &h, NULL);
889  count = pixaGetCount(pixad);
890  if (count == 0) { /* return empty pix */
891  pixd = pixCreateTemplate(pixs);
892  } else {
893  pixd = pixaDisplay(pixad, w, h);
894  pixCopyResolution(pixd, pixs);
895  pixCopyColormap(pixd, pixs);
896  pixCopyText(pixd, pixs);
897  pixCopyInputFormat(pixd, pixs);
898  }
899  pixaDestroy(&pixad);
900  return pixd;
901 }
902 
903 
925 PIXA *
927  l_float32 thresh,
928  l_int32 type,
929  l_int32 *pchanged)
930 {
931 NUMA *na, *nai;
932 PIXA *pixad;
933 
934  PROCNAME("pixaSelectByArea");
935 
936  if (!pixas)
937  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
938  if (type != L_SELECT_IF_LT && type != L_SELECT_IF_GT &&
939  type != L_SELECT_IF_LTE && type != L_SELECT_IF_GTE)
940  return (PIXA *)ERROR_PTR("invalid type", procName, NULL);
941 
942  /* Compute area of each component */
943  na = pixaCountPixels(pixas);
944 
945  /* Generate indicator array for elements to be saved. */
946  nai = numaMakeThresholdIndicator(na, thresh, type);
947  numaDestroy(&na);
948 
949  /* Filter to get output */
950  pixad = pixaSelectWithIndicator(pixas, nai, pchanged);
951 
952  numaDestroy(&nai);
953  return pixad;
954 }
955 
956 
980 PIX *
982  l_float32 thresh,
983  l_int32 connectivity,
984  l_int32 type,
985  l_int32 *pchanged)
986 {
987 l_int32 w, h, empty, changed, count;
988 BOXA *boxa;
989 PIX *pixd;
990 PIXA *pixas, *pixad;
991 
992  PROCNAME("pixSelectByWidthHeightRatio");
993 
994  if (!pixs)
995  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
996  if (connectivity != 4 && connectivity != 8)
997  return (PIX *)ERROR_PTR("connectivity not 4 or 8", procName, NULL);
998  if (type != L_SELECT_IF_LT && type != L_SELECT_IF_GT &&
999  type != L_SELECT_IF_LTE && type != L_SELECT_IF_GTE)
1000  return (PIX *)ERROR_PTR("invalid type", procName, NULL);
1001  if (pchanged) *pchanged = FALSE;
1002 
1003  /* Check if any components exist */
1004  pixZero(pixs, &empty);
1005  if (empty)
1006  return pixCopy(NULL, pixs);
1007 
1008  /* Filter components */
1009  boxa = pixConnComp(pixs, &pixas, connectivity);
1010  pixad = pixaSelectByWidthHeightRatio(pixas, thresh, type, &changed);
1011  boxaDestroy(&boxa);
1012  pixaDestroy(&pixas);
1013 
1014  if (!changed) {
1015  pixaDestroy(&pixad);
1016  return pixCopy(NULL, pixs);
1017  }
1018 
1019  /* Render the result */
1020  if (pchanged) *pchanged = TRUE;
1021  pixGetDimensions(pixs, &w, &h, NULL);
1022  count = pixaGetCount(pixad);
1023  if (count == 0) { /* return empty pix */
1024  pixd = pixCreateTemplate(pixs);
1025  } else {
1026  pixd = pixaDisplay(pixad, w, h);
1027  pixCopyResolution(pixd, pixs);
1028  pixCopyColormap(pixd, pixs);
1029  pixCopyText(pixd, pixs);
1030  pixCopyInputFormat(pixd, pixs);
1031  }
1032  pixaDestroy(&pixad);
1033  return pixd;
1034 }
1035 
1036 
1058 PIXA *
1060  l_float32 thresh,
1061  l_int32 type,
1062  l_int32 *pchanged)
1063 {
1064 NUMA *na, *nai;
1065 PIXA *pixad;
1066 
1067  PROCNAME("pixaSelectByWidthHeightRatio");
1068 
1069  if (!pixas)
1070  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1071  if (type != L_SELECT_IF_LT && type != L_SELECT_IF_GT &&
1072  type != L_SELECT_IF_LTE && type != L_SELECT_IF_GTE)
1073  return (PIXA *)ERROR_PTR("invalid type", procName, NULL);
1074 
1075  /* Compute component ratios. */
1076  na = pixaFindWidthHeightRatio(pixas);
1077 
1078  /* Generate indicator array for elements to be saved. */
1079  nai = numaMakeThresholdIndicator(na, thresh, type);
1080  numaDestroy(&na);
1081 
1082  /* Filter to get output */
1083  pixad = pixaSelectWithIndicator(pixas, nai, pchanged);
1084 
1085  numaDestroy(&nai);
1086  return pixad;
1087 }
1088 
1089 
1108 PIXA *
1110  l_int32 nmin,
1111  l_int32 nmax,
1112  l_int32 connectivity,
1113  l_int32 *pchanged)
1114 {
1115 l_int32 n, i, count;
1116 NUMA *na;
1117 PIX *pix;
1118 PIXA *pixad;
1119 
1120  PROCNAME("pixaSelectByNumConnComp");
1121 
1122  if (pchanged) *pchanged = 0;
1123  if (!pixas)
1124  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1125  if (nmin > nmax)
1126  return (PIXA *)ERROR_PTR("nmin > nmax", procName, NULL);
1127  if (connectivity != 4 && connectivity != 8)
1128  return (PIXA *)ERROR_PTR("connectivity not 4 or 8", procName, NULL);
1129 
1130  /* Get indicator array based on number of c.c. */
1131  n = pixaGetCount(pixas);
1132  na = numaCreate(n);
1133  for (i = 0; i < n; i++) {
1134  pix = pixaGetPix(pixas, i, L_CLONE);
1135  pixCountConnComp(pix, connectivity, &count);
1136  if (count >= nmin && count <= nmax)
1137  numaAddNumber(na, 1);
1138  else
1139  numaAddNumber(na, 0);
1140  pixDestroy(&pix);
1141  }
1142 
1143  /* Filter to get output */
1144  pixad = pixaSelectWithIndicator(pixas, na, pchanged);
1145  numaDestroy(&na);
1146  return pixad;
1147 }
1148 
1149 
1167 PIXA *
1169  NUMA *na,
1170  l_int32 *pchanged)
1171 {
1172 l_int32 i, n, nbox, ival, nsave;
1173 BOX *box;
1174 PIX *pix1;
1175 PIXA *pixad;
1176 
1177  PROCNAME("pixaSelectWithIndicator");
1178 
1179  if (!pixas)
1180  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1181  if (!na)
1182  return (PIXA *)ERROR_PTR("na not defined", procName, NULL);
1183 
1184  nsave = 0;
1185  n = numaGetCount(na);
1186  for (i = 0; i < n; i++) {
1187  numaGetIValue(na, i, &ival);
1188  if (ival == 1) nsave++;
1189  }
1190 
1191  if (nsave == n) {
1192  if (pchanged) *pchanged = FALSE;
1193  return pixaCopy(pixas, L_CLONE);
1194  }
1195  if (pchanged) *pchanged = TRUE;
1196  pixad = pixaCreate(nsave);
1197  nbox = pixaGetBoxaCount(pixas);
1198  for (i = 0; i < n; i++) {
1199  numaGetIValue(na, i, &ival);
1200  if (ival == 0) continue;
1201  pix1 = pixaGetPix(pixas, i, L_CLONE);
1202  pixaAddPix(pixad, pix1, L_INSERT);
1203  if (nbox == n) { /* fully populated boxa */
1204  box = pixaGetBox(pixas, i, L_CLONE);
1205  pixaAddBox(pixad, box, L_INSERT);
1206  }
1207  }
1208 
1209  return pixad;
1210 }
1211 
1212 
1227 l_ok
1229  PIXA *pixa,
1230  NUMA *na)
1231 {
1232 l_int32 i, n, ival, x, y, w, h;
1233 BOX *box;
1234 PIX *pix;
1235 
1236  PROCNAME("pixRemoveWithIndicator");
1237 
1238  if (!pixs)
1239  return ERROR_INT("pixs not defined", procName, 1);
1240  if (!pixa)
1241  return ERROR_INT("pixa not defined", procName, 1);
1242  if (!na)
1243  return ERROR_INT("na not defined", procName, 1);
1244  n = pixaGetCount(pixa);
1245  if (n != numaGetCount(na))
1246  return ERROR_INT("pixa and na sizes not equal", procName, 1);
1247 
1248  for (i = 0; i < n; i++) {
1249  numaGetIValue(na, i, &ival);
1250  if (ival == 1) {
1251  pix = pixaGetPix(pixa, i, L_CLONE);
1252  box = pixaGetBox(pixa, i, L_CLONE);
1253  boxGetGeometry(box, &x, &y, &w, &h);
1254  pixRasterop(pixs, x, y, w, h, PIX_DST & PIX_NOT(PIX_SRC),
1255  pix, 0, 0);
1256  boxDestroy(&box);
1257  pixDestroy(&pix);
1258  }
1259  }
1260 
1261  return 0;
1262 }
1263 
1264 
1280 l_ok
1282  PIXA *pixa,
1283  NUMA *na)
1284 {
1285 l_int32 i, n, ival, x, y, w, h;
1286 BOX *box;
1287 PIX *pix;
1288 
1289  PROCNAME("pixAddWithIndicator");
1290 
1291  if (!pixs)
1292  return ERROR_INT("pixs not defined", procName, 1);
1293  if (!pixa)
1294  return ERROR_INT("pixa not defined", procName, 1);
1295  if (!na)
1296  return ERROR_INT("na not defined", procName, 1);
1297  n = pixaGetCount(pixa);
1298  if (n != numaGetCount(na))
1299  return ERROR_INT("pixa and na sizes not equal", procName, 1);
1300 
1301  for (i = 0; i < n; i++) {
1302  numaGetIValue(na, i, &ival);
1303  if (ival == 1) {
1304  pix = pixaGetPix(pixa, i, L_CLONE);
1305  box = pixaGetBox(pixa, i, L_CLONE);
1306  boxGetGeometry(box, &x, &y, &w, &h);
1307  pixRasterop(pixs, x, y, w, h, PIX_SRC | PIX_DST, pix, 0, 0);
1308  boxDestroy(&box);
1309  pixDestroy(&pix);
1310  }
1311  }
1312 
1313  return 0;
1314 }
1315 
1316 
1333 PIXA *
1335  const char *str,
1336  l_int32 *perror)
1337 {
1338 l_int32 i, nval, npix, nbox, val, imaxval;
1339 l_float32 maxval;
1340 BOX *box;
1341 NUMA *na;
1342 PIX *pix1;
1343 PIXA *pixad;
1344 
1345  PROCNAME("pixaSelectWithString");
1346 
1347  if (perror) *perror = 0;
1348  if (!pixas)
1349  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1350  if (!str)
1351  return (PIXA *)ERROR_PTR("str not defined", procName, NULL);
1352 
1353  if ((na = numaCreateFromString(str)) == NULL)
1354  return (PIXA *)ERROR_PTR("na not made", procName, NULL);
1355  if ((nval = numaGetCount(na)) == 0) {
1356  numaDestroy(&na);
1357  return (PIXA *)ERROR_PTR("no indices found", procName, NULL);
1358  }
1359  numaGetMax(na, &maxval, NULL);
1360  imaxval = (l_int32)(maxval + 0.1);
1361  nbox = pixaGetBoxaCount(pixas);
1362  npix = pixaGetCount(pixas);
1363  if (imaxval >= npix) {
1364  if (perror) *perror = 1;
1365  L_ERROR("max index = %d, size of pixa = %d\n", procName, imaxval, npix);
1366  }
1367 
1368  pixad = pixaCreate(nval);
1369  for (i = 0; i < nval; i++) {
1370  numaGetIValue(na, i, &val);
1371  if (val < 0 || val >= npix) {
1372  L_ERROR("index %d out of range of pix\n", procName, val);
1373  continue;
1374  }
1375  pix1 = pixaGetPix(pixas, val, L_COPY);
1376  pixaAddPix(pixad, pix1, L_INSERT);
1377  if (nbox == npix) { /* fully populated boxa */
1378  box = pixaGetBox(pixas, val, L_COPY);
1379  pixaAddBox(pixad, box, L_INSERT);
1380  }
1381  }
1382  numaDestroy(&na);
1383  return pixad;
1384 }
1385 
1386 
1404 PIX *
1406  PIXA *pixa,
1407  l_int32 index)
1408 {
1409 l_int32 n, x, y, w, h, same, maxd;
1410 BOX *box;
1411 BOXA *boxa;
1412 PIX *pix;
1413 
1414  PROCNAME("pixaRenderComponent");
1415 
1416  if (!pixa)
1417  return (PIX *)ERROR_PTR("pixa not defined", procName, pixs);
1418  n = pixaGetCount(pixa);
1419  if (index < 0 || index >= n)
1420  return (PIX *)ERROR_PTR("invalid index", procName, pixs);
1421  if (pixs && (pixGetDepth(pixs) != 1))
1422  return (PIX *)ERROR_PTR("pixs not 1 bpp", procName, pixs);
1423  pixaVerifyDepth(pixa, &same, &maxd);
1424  if (maxd > 1)
1425  return (PIX *)ERROR_PTR("not all pix with d == 1", procName, pixs);
1426 
1427  boxa = pixaGetBoxa(pixa, L_CLONE);
1428  if (!pixs) {
1429  boxaGetExtent(boxa, &w, &h, NULL);
1430  pixs = pixCreate(w, h, 1);
1431  }
1432 
1433  pix = pixaGetPix(pixa, index, L_CLONE);
1434  box = boxaGetBox(boxa, index, L_CLONE);
1435  boxGetGeometry(box, &x, &y, &w, &h);
1436  pixRasterop(pixs, x, y, w, h, PIX_SRC | PIX_DST, pix, 0, 0);
1437  boxDestroy(&box);
1438  pixDestroy(&pix);
1439  boxaDestroy(&boxa);
1440 
1441  return pixs;
1442 }
1443 
1444 
1445 /*---------------------------------------------------------------------*
1446  * Sort functions *
1447  *---------------------------------------------------------------------*/
1474 PIXA *
1476  l_int32 sorttype,
1477  l_int32 sortorder,
1478  NUMA **pnaindex,
1479  l_int32 copyflag)
1480 {
1481 l_int32 i, n, nb, x, y, w, h;
1482 BOXA *boxa;
1483 NUMA *na, *naindex;
1484 PIXA *pixad;
1485 
1486  PROCNAME("pixaSort");
1487 
1488  if (pnaindex) *pnaindex = NULL;
1489  if (!pixas)
1490  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1491  if (sorttype != L_SORT_BY_X && sorttype != L_SORT_BY_Y &&
1492  sorttype != L_SORT_BY_WIDTH && sorttype != L_SORT_BY_HEIGHT &&
1493  sorttype != L_SORT_BY_MIN_DIMENSION &&
1494  sorttype != L_SORT_BY_MAX_DIMENSION &&
1495  sorttype != L_SORT_BY_PERIMETER &&
1496  sorttype != L_SORT_BY_AREA &&
1497  sorttype != L_SORT_BY_ASPECT_RATIO)
1498  return (PIXA *)ERROR_PTR("invalid sort type", procName, NULL);
1499  if (sortorder != L_SORT_INCREASING && sortorder != L_SORT_DECREASING)
1500  return (PIXA *)ERROR_PTR("invalid sort order", procName, NULL);
1501  if (copyflag != L_COPY && copyflag != L_CLONE)
1502  return (PIXA *)ERROR_PTR("invalid copy flag", procName, NULL);
1503 
1504  /* Check the pixa and boxa counts. Make a boxa if required. */
1505  if ((n = pixaGetCount(pixas)) == 0) {
1506  L_INFO("no pix in pixa\n", procName);
1507  return pixaCopy(pixas, copyflag);
1508  }
1509  if ((boxa = pixas->boxa) == NULL) /* not owned; do not destroy */
1510  return (PIXA *)ERROR_PTR("boxa not found!", procName, NULL);
1511  nb = boxaGetCount(boxa);
1512  if (nb == 0) {
1513  pixaSetFullSizeBoxa(pixas);
1514  nb = n;
1515  boxa = pixas->boxa; /* not owned */
1516  if (sorttype == L_SORT_BY_X || sorttype == L_SORT_BY_Y)
1517  L_WARNING("sort by x or y where all values are 0\n", procName);
1518  }
1519  if (nb != n)
1520  return (PIXA *)ERROR_PTR("boxa and pixa counts differ", procName, NULL);
1521 
1522  /* Use O(n) binsort if possible */
1523  if (n > MinCompsForBinSort &&
1524  ((sorttype == L_SORT_BY_X) || (sorttype == L_SORT_BY_Y) ||
1525  (sorttype == L_SORT_BY_WIDTH) || (sorttype == L_SORT_BY_HEIGHT) ||
1526  (sorttype == L_SORT_BY_PERIMETER)))
1527  return pixaBinSort(pixas, sorttype, sortorder, pnaindex, copyflag);
1528 
1529  /* Build up numa of specific data */
1530  if ((na = numaCreate(n)) == NULL)
1531  return (PIXA *)ERROR_PTR("na not made", procName, NULL);
1532  for (i = 0; i < n; i++) {
1533  boxaGetBoxGeometry(boxa, i, &x, &y, &w, &h);
1534  switch (sorttype)
1535  {
1536  case L_SORT_BY_X:
1537  numaAddNumber(na, x);
1538  break;
1539  case L_SORT_BY_Y:
1540  numaAddNumber(na, y);
1541  break;
1542  case L_SORT_BY_WIDTH:
1543  numaAddNumber(na, w);
1544  break;
1545  case L_SORT_BY_HEIGHT:
1546  numaAddNumber(na, h);
1547  break;
1549  numaAddNumber(na, L_MIN(w, h));
1550  break;
1552  numaAddNumber(na, L_MAX(w, h));
1553  break;
1554  case L_SORT_BY_PERIMETER:
1555  numaAddNumber(na, w + h);
1556  break;
1557  case L_SORT_BY_AREA:
1558  numaAddNumber(na, w * h);
1559  break;
1561  numaAddNumber(na, (l_float32)w / (l_float32)h);
1562  break;
1563  default:
1564  L_WARNING("invalid sort type\n", procName);
1565  }
1566  }
1567 
1568  /* Get the sort index for data array */
1569  naindex = numaGetSortIndex(na, sortorder);
1570  numaDestroy(&na);
1571  if (!naindex)
1572  return (PIXA *)ERROR_PTR("naindex not made", procName, NULL);
1573 
1574  /* Build up sorted pixa using sort index */
1575  if ((pixad = pixaSortByIndex(pixas, naindex, copyflag)) == NULL) {
1576  numaDestroy(&naindex);
1577  return (PIXA *)ERROR_PTR("pixad not made", procName, NULL);
1578  }
1579 
1580  if (pnaindex)
1581  *pnaindex = naindex;
1582  else
1583  numaDestroy(&naindex);
1584  return pixad;
1585 }
1586 
1587 
1614 PIXA *
1616  l_int32 sorttype,
1617  l_int32 sortorder,
1618  NUMA **pnaindex,
1619  l_int32 copyflag)
1620 {
1621 l_int32 i, n, x, y, w, h;
1622 BOXA *boxa;
1623 NUMA *na, *naindex;
1624 PIXA *pixad;
1625 
1626  PROCNAME("pixaBinSort");
1627 
1628  if (pnaindex) *pnaindex = NULL;
1629  if (!pixas)
1630  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1631  if (sorttype != L_SORT_BY_X && sorttype != L_SORT_BY_Y &&
1632  sorttype != L_SORT_BY_WIDTH && sorttype != L_SORT_BY_HEIGHT &&
1633  sorttype != L_SORT_BY_PERIMETER)
1634  return (PIXA *)ERROR_PTR("invalid sort type", procName, NULL);
1635  if (sortorder != L_SORT_INCREASING && sortorder != L_SORT_DECREASING)
1636  return (PIXA *)ERROR_PTR("invalid sort order", procName, NULL);
1637  if (copyflag != L_COPY && copyflag != L_CLONE)
1638  return (PIXA *)ERROR_PTR("invalid copy flag", procName, NULL);
1639 
1640  /* Verify that the pixa and its boxa have the same count */
1641  if ((boxa = pixas->boxa) == NULL) /* not owned; do not destroy */
1642  return (PIXA *)ERROR_PTR("boxa not found", procName, NULL);
1643  n = pixaGetCount(pixas);
1644  if (boxaGetCount(boxa) != n)
1645  return (PIXA *)ERROR_PTR("boxa and pixa counts differ", procName, NULL);
1646 
1647  /* Generate Numa of appropriate box dimensions */
1648  if ((na = numaCreate(n)) == NULL)
1649  return (PIXA *)ERROR_PTR("na not made", procName, NULL);
1650  for (i = 0; i < n; i++) {
1651  boxaGetBoxGeometry(boxa, i, &x, &y, &w, &h);
1652  switch (sorttype)
1653  {
1654  case L_SORT_BY_X:
1655  numaAddNumber(na, x);
1656  break;
1657  case L_SORT_BY_Y:
1658  numaAddNumber(na, y);
1659  break;
1660  case L_SORT_BY_WIDTH:
1661  numaAddNumber(na, w);
1662  break;
1663  case L_SORT_BY_HEIGHT:
1664  numaAddNumber(na, h);
1665  break;
1666  case L_SORT_BY_PERIMETER:
1667  numaAddNumber(na, w + h);
1668  break;
1669  default:
1670  L_WARNING("invalid sort type\n", procName);
1671  }
1672  }
1673 
1674  /* Get the sort index for data array */
1675  naindex = numaGetBinSortIndex(na, sortorder);
1676  numaDestroy(&na);
1677  if (!naindex)
1678  return (PIXA *)ERROR_PTR("naindex not made", procName, NULL);
1679 
1680  /* Build up sorted pixa using sort index */
1681  if ((pixad = pixaSortByIndex(pixas, naindex, copyflag)) == NULL) {
1682  numaDestroy(&naindex);
1683  return (PIXA *)ERROR_PTR("pixad not made", procName, NULL);
1684  }
1685 
1686  if (pnaindex)
1687  *pnaindex = naindex;
1688  else
1689  numaDestroy(&naindex);
1690  return pixad;
1691 }
1692 
1693 
1702 PIXA *
1704  NUMA *naindex,
1705  l_int32 copyflag)
1706 {
1707 l_int32 i, n, index;
1708 BOX *box;
1709 PIX *pix;
1710 PIXA *pixad;
1711 
1712  PROCNAME("pixaSortByIndex");
1713 
1714  if (!pixas)
1715  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1716  if (!naindex)
1717  return (PIXA *)ERROR_PTR("naindex not defined", procName, NULL);
1718  if (copyflag != L_CLONE && copyflag != L_COPY)
1719  return (PIXA *)ERROR_PTR("invalid copyflag", procName, NULL);
1720 
1721  n = pixaGetCount(pixas);
1722  pixad = pixaCreate(n);
1723  for (i = 0; i < n; i++) {
1724  numaGetIValue(naindex, i, &index);
1725  pix = pixaGetPix(pixas, index, copyflag);
1726  box = pixaGetBox(pixas, index, copyflag);
1727  pixaAddPix(pixad, pix, L_INSERT);
1728  pixaAddBox(pixad, box, L_INSERT);
1729  }
1730 
1731  return pixad;
1732 }
1733 
1734 
1743 PIXAA *
1745  NUMAA *naa,
1746  l_int32 copyflag)
1747 {
1748 l_int32 pixtot, ntot, i, j, n, nn, index;
1749 BOX *box;
1750 NUMA *na;
1751 PIX *pix;
1752 PIXA *pixa;
1753 PIXAA *paa;
1754 
1755  PROCNAME("pixaSort2dByIndex");
1756 
1757  if (!pixas)
1758  return (PIXAA *)ERROR_PTR("pixas not defined", procName, NULL);
1759  if (!naa)
1760  return (PIXAA *)ERROR_PTR("naindex not defined", procName, NULL);
1761 
1762  /* Check counts */
1763  ntot = numaaGetNumberCount(naa);
1764  pixtot = pixaGetCount(pixas);
1765  if (ntot != pixtot)
1766  return (PIXAA *)ERROR_PTR("element count mismatch", procName, NULL);
1767 
1768  n = numaaGetCount(naa);
1769  paa = pixaaCreate(n);
1770  for (i = 0; i < n; i++) {
1771  na = numaaGetNuma(naa, i, L_CLONE);
1772  nn = numaGetCount(na);
1773  pixa = pixaCreate(nn);
1774  for (j = 0; j < nn; j++) {
1775  numaGetIValue(na, j, &index);
1776  pix = pixaGetPix(pixas, index, copyflag);
1777  box = pixaGetBox(pixas, index, copyflag);
1778  pixaAddPix(pixa, pix, L_INSERT);
1779  pixaAddBox(pixa, box, L_INSERT);
1780  }
1781  pixaaAddPixa(paa, pixa, L_INSERT);
1782  numaDestroy(&na);
1783  }
1784 
1785  return paa;
1786 }
1787 
1788 
1789 /*---------------------------------------------------------------------*
1790  * Pixa and Pixaa range selection *
1791  *---------------------------------------------------------------------*/
1808 PIXA *
1810  l_int32 first,
1811  l_int32 last,
1812  l_int32 copyflag)
1813 {
1814 l_int32 n, npix, i;
1815 PIX *pix;
1816 PIXA *pixad;
1817 
1818  PROCNAME("pixaSelectRange");
1819 
1820  if (!pixas)
1821  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1822  if (copyflag != L_COPY && copyflag != L_CLONE)
1823  return (PIXA *)ERROR_PTR("invalid copyflag", procName, NULL);
1824  n = pixaGetCount(pixas);
1825  first = L_MAX(0, first);
1826  if (last < 0) last = n - 1;
1827  if (first >= n)
1828  return (PIXA *)ERROR_PTR("invalid first", procName, NULL);
1829  if (last >= n) {
1830  L_WARNING("last = %d is beyond max index = %d; adjusting\n",
1831  procName, last, n - 1);
1832  last = n - 1;
1833  }
1834  if (first > last)
1835  return (PIXA *)ERROR_PTR("first > last", procName, NULL);
1836 
1837  npix = last - first + 1;
1838  pixad = pixaCreate(npix);
1839  for (i = first; i <= last; i++) {
1840  pix = pixaGetPix(pixas, i, copyflag);
1841  pixaAddPix(pixad, pix, L_INSERT);
1842  }
1843  return pixad;
1844 }
1845 
1846 
1863 PIXAA *
1865  l_int32 first,
1866  l_int32 last,
1867  l_int32 copyflag)
1868 {
1869 l_int32 n, npixa, i;
1870 PIXA *pixa;
1871 PIXAA *paad;
1872 
1873  PROCNAME("pixaaSelectRange");
1874 
1875  if (!paas)
1876  return (PIXAA *)ERROR_PTR("paas not defined", procName, NULL);
1877  if (copyflag != L_COPY && copyflag != L_CLONE)
1878  return (PIXAA *)ERROR_PTR("invalid copyflag", procName, NULL);
1879  n = pixaaGetCount(paas, NULL);
1880  first = L_MAX(0, first);
1881  if (last < 0) last = n - 1;
1882  if (first >= n)
1883  return (PIXAA *)ERROR_PTR("invalid first", procName, NULL);
1884  if (last >= n) {
1885  L_WARNING("last = %d is beyond max index = %d; adjusting\n",
1886  procName, last, n - 1);
1887  last = n - 1;
1888  }
1889  if (first > last)
1890  return (PIXAA *)ERROR_PTR("first > last", procName, NULL);
1891 
1892  npixa = last - first + 1;
1893  paad = pixaaCreate(npixa);
1894  for (i = first; i <= last; i++) {
1895  pixa = pixaaGetPixa(paas, i, copyflag);
1896  pixaaAddPixa(paad, pixa, L_INSERT);
1897  }
1898  return paad;
1899 }
1900 
1901 
1902 /*---------------------------------------------------------------------*
1903  * Pixa and Pixaa scaling *
1904  *---------------------------------------------------------------------*/
1924 PIXAA *
1926  l_int32 wd,
1927  l_int32 hd)
1928 {
1929 l_int32 n, i;
1930 PIXA *pixa1, *pixa2;
1931 PIXAA *paad;
1932 
1933  PROCNAME("pixaaScaleToSize");
1934 
1935  if (!paas)
1936  return (PIXAA *)ERROR_PTR("paas not defined", procName, NULL);
1937  if (wd <= 0 && hd <= 0)
1938  return (PIXAA *)ERROR_PTR("neither wd nor hd > 0", procName, NULL);
1939 
1940  n = pixaaGetCount(paas, NULL);
1941  paad = pixaaCreate(n);
1942  for (i = 0; i < n; i++) {
1943  pixa1 = pixaaGetPixa(paas, i, L_CLONE);
1944  pixa2 = pixaScaleToSize(pixa1, wd, hd);
1945  pixaaAddPixa(paad, pixa2, L_INSERT);
1946  pixaDestroy(&pixa1);
1947  }
1948  return paad;
1949 }
1950 
1951 
1973 PIXAA *
1975  NUMA *nawd,
1976  NUMA *nahd)
1977 {
1978 l_int32 n, i, wd, hd;
1979 PIXA *pixa1, *pixa2;
1980 PIXAA *paad;
1981 
1982  PROCNAME("pixaaScaleToSizeVar");
1983 
1984  if (!paas)
1985  return (PIXAA *)ERROR_PTR("paas not defined", procName, NULL);
1986  if (!nawd && !nahd)
1987  return (PIXAA *)ERROR_PTR("!nawd && !nahd", procName, NULL);
1988 
1989  n = pixaaGetCount(paas, NULL);
1990  if (nawd && (n != numaGetCount(nawd)))
1991  return (PIXAA *)ERROR_PTR("nawd wrong size", procName, NULL);
1992  if (nahd && (n != numaGetCount(nahd)))
1993  return (PIXAA *)ERROR_PTR("nahd wrong size", procName, NULL);
1994  paad = pixaaCreate(n);
1995  for (i = 0; i < n; i++) {
1996  wd = hd = 0;
1997  if (nawd) numaGetIValue(nawd, i, &wd);
1998  if (nahd) numaGetIValue(nahd, i, &hd);
1999  pixa1 = pixaaGetPixa(paas, i, L_CLONE);
2000  pixa2 = pixaScaleToSize(pixa1, wd, hd);
2001  pixaaAddPixa(paad, pixa2, L_INSERT);
2002  pixaDestroy(&pixa1);
2003  }
2004  return paad;
2005 }
2006 
2007 
2021 PIXA *
2023  l_int32 wd,
2024  l_int32 hd)
2025 {
2026 l_int32 n, i;
2027 PIX *pix1, *pix2;
2028 PIXA *pixad;
2029 
2030  PROCNAME("pixaScaleToSize");
2031 
2032  if (!pixas)
2033  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
2034 
2035  if (wd <= 0 && hd <= 0) /* no scaling requested */
2036  return pixaCopy(pixas, L_CLONE);
2037 
2038  n = pixaGetCount(pixas);
2039  pixad = pixaCreate(n);
2040  for (i = 0; i < n; i++) {
2041  pix1 = pixaGetPix(pixas, i, L_CLONE);
2042  pix2 = pixScaleToSize(pix1, wd, hd);
2043  pixCopyText(pix2, pix1);
2044  pixaAddPix(pixad, pix2, L_INSERT);
2045  pixDestroy(&pix1);
2046  }
2047  return pixad;
2048 }
2049 
2050 
2066 PIXA *
2068  l_int32 delw,
2069  l_int32 delh)
2070 {
2071 l_int32 n, i;
2072 PIX *pix1, *pix2;
2073 PIXA *pixad;
2074 
2075  PROCNAME("pixaScaleToSizeRel");
2076 
2077  if (!pixas)
2078  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
2079 
2080  n = pixaGetCount(pixas);
2081  pixad = pixaCreate(n);
2082  for (i = 0; i < n; i++) {
2083  pix1 = pixaGetPix(pixas, i, L_CLONE);
2084  pix2 = pixScaleToSizeRel(pix1, delw, delh);
2085  if (pix2) {
2086  pixaAddPix(pixad, pix2, L_INSERT);
2087  } else {
2088  L_WARNING("relative scale to size failed; use a copy\n", procName);
2089  pixaAddPix(pixad, pix1, L_COPY);
2090  }
2091  pixDestroy(&pix1);
2092  }
2093  return pixad;
2094 }
2095 
2096 
2110 PIXA *
2112  l_float32 scalex,
2113  l_float32 scaley)
2114 {
2115 l_int32 i, n, nb;
2116 BOXA *boxa1, *boxa2;
2117 PIX *pix1, *pix2;
2118 PIXA *pixad;
2119 
2120  PROCNAME("pixaScale");
2121 
2122  if (!pixas)
2123  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
2124  if (scalex <= 0.0 || scaley <= 0.0)
2125  return (PIXA *)ERROR_PTR("invalid scaling parameters", procName, NULL);
2126 
2127  n = pixaGetCount(pixas);
2128  pixad = pixaCreate(n);
2129  for (i = 0; i < n; i++) {
2130  pix1 = pixaGetPix(pixas, i, L_CLONE);
2131  pix2 = pixScale(pix1, scalex, scaley);
2132  pixCopyText(pix2, pix1);
2133  pixaAddPix(pixad, pix2, L_INSERT);
2134  pixDestroy(&pix1);
2135  }
2136 
2137  boxa1 = pixaGetBoxa(pixas, L_CLONE);
2138  nb = boxaGetCount(boxa1);
2139  if (nb == n) {
2140  boxa2 = boxaTransform(boxa1, 0, 0, scalex, scaley);
2141  pixaSetBoxa(pixad, boxa2, L_INSERT);
2142  }
2143  boxaDestroy(&boxa1);
2144  return pixad;
2145 }
2146 
2147 
2161 PIXA *
2163  l_float32 scalex,
2164  l_float32 scaley)
2165 {
2166 l_int32 i, n, nb;
2167 BOXA *boxa1, *boxa2;
2168 PIX *pix1, *pix2;
2169 PIXA *pixad;
2170 
2171  PROCNAME("pixaScaleBySampling");
2172 
2173  if (!pixas)
2174  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
2175  if (scalex <= 0.0 || scaley <= 0.0)
2176  return (PIXA *)ERROR_PTR("invalid scaling parameters", procName, NULL);
2177 
2178  n = pixaGetCount(pixas);
2179  pixad = pixaCreate(n);
2180  for (i = 0; i < n; i++) {
2181  pix1 = pixaGetPix(pixas, i, L_CLONE);
2182  pix2 = pixScaleBySampling(pix1, scalex, scaley);
2183  pixCopyText(pix2, pix1);
2184  pixaAddPix(pixad, pix2, L_INSERT);
2185  pixDestroy(&pix1);
2186  }
2187 
2188  boxa1 = pixaGetBoxa(pixas, L_CLONE);
2189  nb = boxaGetCount(boxa1);
2190  if (nb == n) {
2191  boxa2 = boxaTransform(boxa1, 0, 0, scalex, scaley);
2192  pixaSetBoxa(pixad, boxa2, L_INSERT);
2193  }
2194  boxaDestroy(&boxa1);
2195  return pixad;
2196 }
2197 
2198 
2199 /*---------------------------------------------------------------------*
2200  * Pixa rotation and translation *
2201  *---------------------------------------------------------------------*/
2226 PIXA *
2228  l_float32 angle,
2229  l_int32 type,
2230  l_int32 incolor,
2231  l_int32 width,
2232  l_int32 height)
2233 {
2234 l_int32 i, n;
2235 BOXA *boxa;
2236 PIX *pixs, *pixd;
2237 PIXA *pixad;
2238 
2239  PROCNAME("pixaRotate");
2240 
2241  if (!pixas)
2242  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
2243  if (type != L_ROTATE_SHEAR && type != L_ROTATE_AREA_MAP &&
2244  type != L_ROTATE_SAMPLING)
2245  return (PIXA *)ERROR_PTR("invalid type", procName, NULL);
2246  if (incolor != L_BRING_IN_WHITE && incolor != L_BRING_IN_BLACK)
2247  return (PIXA *)ERROR_PTR("invalid incolor", procName, NULL);
2248  if (L_ABS(angle) < MinAngleToRotate)
2249  return pixaCopy(pixas, L_COPY);
2250 
2251  n = pixaGetCount(pixas);
2252  if ((pixad = pixaCreate(n)) == NULL)
2253  return (PIXA *)ERROR_PTR("pixad not made", procName, NULL);
2254  boxa = pixaGetBoxa(pixad, L_COPY);
2255  pixaSetBoxa(pixad, boxa, L_INSERT);
2256  for (i = 0; i < n; i++) {
2257  if ((pixs = pixaGetPix(pixas, i, L_CLONE)) == NULL) {
2258  pixaDestroy(&pixad);
2259  return (PIXA *)ERROR_PTR("pixs not found", procName, NULL);
2260  }
2261  pixd = pixRotate(pixs, angle, type, incolor, width, height);
2262  pixaAddPix(pixad, pixd, L_INSERT);
2263  pixDestroy(&pixs);
2264  }
2265 
2266  return pixad;
2267 }
2268 
2269 
2284 PIXA *
2286  l_int32 rotation)
2287 {
2288 l_int32 i, n, nb, w, h;
2289 BOX *boxs, *boxd;
2290 PIX *pixs, *pixd;
2291 PIXA *pixad;
2292 
2293  PROCNAME("pixaRotateOrth");
2294 
2295  if (!pixas)
2296  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
2297  if (rotation < 0 || rotation > 3)
2298  return (PIXA *)ERROR_PTR("rotation not in {0,1,2,3}", procName, NULL);
2299  if (rotation == 0)
2300  return pixaCopy(pixas, L_COPY);
2301 
2302  n = pixaGetCount(pixas);
2303  nb = pixaGetBoxaCount(pixas);
2304  if ((pixad = pixaCreate(n)) == NULL)
2305  return (PIXA *)ERROR_PTR("pixad not made", procName, NULL);
2306  for (i = 0; i < n; i++) {
2307  if ((pixs = pixaGetPix(pixas, i, L_CLONE)) == NULL) {
2308  pixaDestroy(&pixad);
2309  return (PIXA *)ERROR_PTR("pixs not found", procName, NULL);
2310  }
2311  pixd = pixRotateOrth(pixs, rotation);
2312  pixaAddPix(pixad, pixd, L_INSERT);
2313  if (n == nb) {
2314  boxs = pixaGetBox(pixas, i, L_COPY);
2315  pixGetDimensions(pixs, &w, &h, NULL);
2316  boxd = boxRotateOrth(boxs, w, h, rotation);
2317  pixaAddBox(pixad, boxd, L_INSERT);
2318  boxDestroy(&boxs);
2319  }
2320  pixDestroy(&pixs);
2321  }
2322 
2323  return pixad;
2324 }
2325 
2326 
2336 PIXA *
2338  l_int32 hshift,
2339  l_int32 vshift,
2340  l_int32 incolor)
2341 {
2342 l_int32 i, n, nb;
2343 BOXA *boxas, *boxad;
2344 PIX *pixs, *pixd;
2345 PIXA *pixad;
2346 
2347  PROCNAME("pixaTranslate");
2348 
2349  if (!pixas)
2350  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
2351  if (hshift == 0 && vshift == 0)
2352  return pixaCopy(pixas, L_COPY);
2353 
2354  n = pixaGetCount(pixas);
2355  nb = pixaGetBoxaCount(pixas);
2356  if ((pixad = pixaCreate(n)) == NULL)
2357  return (PIXA *)ERROR_PTR("pixad not made", procName, NULL);
2358  for (i = 0; i < n; i++) {
2359  if ((pixs = pixaGetPix(pixas, i, L_CLONE)) == NULL) {
2360  pixaDestroy(&pixad);
2361  return (PIXA *)ERROR_PTR("pixs not found", procName, NULL);
2362  }
2363  pixd = pixTranslate(NULL, pixs, hshift, vshift, incolor);
2364  pixaAddPix(pixad, pixd, L_INSERT);
2365  pixDestroy(&pixs);
2366  }
2367  if (n == nb) {
2368  boxas = pixaGetBoxa(pixas, L_CLONE);
2369  boxad = boxaTransform(boxas, hshift, vshift, 1.0, 1.0);
2370  pixaSetBoxa(pixad, boxad, L_INSERT);
2371  boxaDestroy(&boxas);
2372  }
2373 
2374  return pixad;
2375 }
2376 
2377 
2378 /*---------------------------------------------------------------------*
2379  * Miscellaneous functions *
2380  *---------------------------------------------------------------------*/
2410 PIXA *
2412  PIXA *pixas,
2413  l_int32 left,
2414  l_int32 right,
2415  l_int32 top,
2416  l_int32 bot,
2417  l_uint32 val)
2418 {
2419 l_int32 i, n, nbox;
2420 BOX *box;
2421 BOXA *boxad;
2422 PIX *pixs, *pixd;
2423 
2424  PROCNAME("pixaAddBorderGeneral");
2425 
2426  if (!pixas)
2427  return (PIXA *)ERROR_PTR("pixas not defined", procName, pixad);
2428  if (left < 0 || right < 0 || top < 0 || bot < 0)
2429  return (PIXA *)ERROR_PTR("negative border added!", procName, pixad);
2430  if (pixad && (pixad != pixas))
2431  return (PIXA *)ERROR_PTR("pixad defined but != pixas", procName, pixad);
2432 
2433  n = pixaGetCount(pixas);
2434  if (!pixad)
2435  pixad = pixaCreate(n);
2436  for (i = 0; i < n; i++) {
2437  pixs = pixaGetPix(pixas, i, L_CLONE);
2438  pixd = pixAddBorderGeneral(pixs, left, right, top, bot, val);
2439  if (pixad == pixas) /* replace */
2440  pixaReplacePix(pixad, i, pixd, NULL);
2441  else
2442  pixaAddPix(pixad, pixd, L_INSERT);
2443  pixDestroy(&pixs);
2444  }
2445 
2446  nbox = pixaGetBoxaCount(pixas);
2447  boxad = pixaGetBoxa(pixad, L_CLONE);
2448  for (i = 0; i < nbox; i++) {
2449  if ((box = pixaGetBox(pixas, i, L_COPY)) == NULL) {
2450  L_WARNING("box %d not found\n", procName, i);
2451  break;
2452  }
2453  boxAdjustSides(box, box, -left, right, -top, bot);
2454  if (pixad == pixas) /* replace */
2455  boxaReplaceBox(boxad, i, box);
2456  else
2457  boxaAddBox(boxad, box, L_INSERT);
2458  }
2459  boxaDestroy(&boxad);
2460 
2461  return pixad;
2462 }
2463 
2464 
2481 PIXA *
2483  NUMA **pnaindex,
2484  l_int32 copyflag)
2485 {
2486 l_int32 i, j, m, mb, n;
2487 BOX *box;
2488 NUMA *naindex;
2489 PIX *pix;
2490 PIXA *pixa, *pixat;
2491 
2492  PROCNAME("pixaaFlattenToPixa");
2493 
2494  if (pnaindex) *pnaindex = NULL;
2495  if (!paa)
2496  return (PIXA *)ERROR_PTR("paa not defined", procName, NULL);
2497  if (copyflag != L_COPY && copyflag != L_CLONE)
2498  return (PIXA *)ERROR_PTR("invalid copyflag", procName, NULL);
2499 
2500  if (pnaindex) {
2501  naindex = numaCreate(0);
2502  *pnaindex = naindex;
2503  }
2504 
2505  n = pixaaGetCount(paa, NULL);
2506  pixa = pixaCreate(n);
2507  for (i = 0; i < n; i++) {
2508  pixat = pixaaGetPixa(paa, i, L_CLONE);
2509  m = pixaGetCount(pixat);
2510  mb = pixaGetBoxaCount(pixat);
2511  for (j = 0; j < m; j++) {
2512  pix = pixaGetPix(pixat, j, copyflag);
2513  pixaAddPix(pixa, pix, L_INSERT);
2514  if (j < mb) {
2515  box = pixaGetBox(pixat, j, copyflag);
2516  pixaAddBox(pixa, box, L_INSERT);
2517  }
2518  if (pnaindex)
2519  numaAddNumber(naindex, i); /* save 'row' number */
2520  }
2521  pixaDestroy(&pixat);
2522  }
2523 
2524  return pixa;
2525 }
2526 
2527 
2536 l_ok
2538  l_int32 *pminw,
2539  l_int32 *pminh,
2540  l_int32 *pmaxw,
2541  l_int32 *pmaxh)
2542 {
2543 l_int32 minw, minh, maxw, maxh, minpw, minph, maxpw, maxph, i, n;
2544 PIXA *pixa;
2545 
2546  PROCNAME("pixaaSizeRange");
2547 
2548  if (pminw) *pminw = 0;
2549  if (pminh) *pminh = 0;
2550  if (pmaxw) *pmaxw = 0;
2551  if (pmaxh) *pmaxh = 0;
2552  if (!paa)
2553  return ERROR_INT("paa not defined", procName, 1);
2554  if (!pminw && !pmaxw && !pminh && !pmaxh)
2555  return ERROR_INT("no data can be returned", procName, 1);
2556 
2557  minw = minh = 100000000;
2558  maxw = maxh = 0;
2559  n = pixaaGetCount(paa, NULL);
2560  for (i = 0; i < n; i++) {
2561  pixa = pixaaGetPixa(paa, i, L_CLONE);
2562  pixaSizeRange(pixa, &minpw, &minph, &maxpw, &maxph);
2563  if (minpw < minw)
2564  minw = minpw;
2565  if (minph < minh)
2566  minh = minph;
2567  if (maxpw > maxw)
2568  maxw = maxpw;
2569  if (maxph > maxh)
2570  maxh = maxph;
2571  pixaDestroy(&pixa);
2572  }
2573 
2574  if (pminw) *pminw = minw;
2575  if (pminh) *pminh = minh;
2576  if (pmaxw) *pmaxw = maxw;
2577  if (pmaxh) *pmaxh = maxh;
2578  return 0;
2579 }
2580 
2581 
2590 l_ok
2592  l_int32 *pminw,
2593  l_int32 *pminh,
2594  l_int32 *pmaxw,
2595  l_int32 *pmaxh)
2596 {
2597 l_int32 minw, minh, maxw, maxh, i, n, w, h;
2598 PIX *pix;
2599 
2600  PROCNAME("pixaSizeRange");
2601 
2602  if (pminw) *pminw = 0;
2603  if (pminh) *pminh = 0;
2604  if (pmaxw) *pmaxw = 0;
2605  if (pmaxh) *pmaxh = 0;
2606  if (!pixa)
2607  return ERROR_INT("pixa not defined", procName, 1);
2608  if (!pminw && !pmaxw && !pminh && !pmaxh)
2609  return ERROR_INT("no data can be returned", procName, 1);
2610 
2611  minw = minh = 1000000;
2612  maxw = maxh = 0;
2613  n = pixaGetCount(pixa);
2614  for (i = 0; i < n; i++) {
2615  pix = pixaGetPix(pixa, i, L_CLONE);
2616  w = pixGetWidth(pix);
2617  h = pixGetHeight(pix);
2618  if (w < minw)
2619  minw = w;
2620  if (h < minh)
2621  minh = h;
2622  if (w > maxw)
2623  maxw = w;
2624  if (h > maxh)
2625  maxh = h;
2626  pixDestroy(&pix);
2627  }
2628 
2629  if (pminw) *pminw = minw;
2630  if (pminh) *pminh = minh;
2631  if (pmaxw) *pmaxw = maxw;
2632  if (pmaxh) *pmaxh = maxh;
2633 
2634  return 0;
2635 }
2636 
2637 
2660 PIXA *
2662  PIX *pixs)
2663 {
2664 l_int32 i, n;
2665 BOX *box;
2666 PIX *pix, *pixc;
2667 PIXA *pixad;
2668 
2669  PROCNAME("pixaClipToPix");
2670 
2671  if (!pixas)
2672  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
2673  if (!pixs)
2674  return (PIXA *)ERROR_PTR("pixs not defined", procName, NULL);
2675 
2676  n = pixaGetCount(pixas);
2677  if ((pixad = pixaCreate(n)) == NULL)
2678  return (PIXA *)ERROR_PTR("pixad not made", procName, NULL);
2679 
2680  for (i = 0; i < n; i++) {
2681  pix = pixaGetPix(pixas, i, L_CLONE);
2682  box = pixaGetBox(pixas, i, L_COPY);
2683  pixc = pixClipRectangle(pixs, box, NULL);
2684  pixAnd(pixc, pixc, pix);
2685  pixaAddPix(pixad, pixc, L_INSERT);
2686  pixaAddBox(pixad, box, L_INSERT);
2687  pixDestroy(&pix);
2688  }
2689 
2690  return pixad;
2691 }
2692 
2693 
2709 l_ok
2711  PIXA **ppixad,
2712  BOXA **pboxa)
2713 {
2714 l_int32 i, n;
2715 BOX *box1;
2716 PIX *pix1, *pix2;
2717 
2718  PROCNAME("pixaClipToForeground");
2719 
2720  if (ppixad) *ppixad = NULL;
2721  if (pboxa) *pboxa = NULL;
2722  if (!pixas)
2723  return ERROR_INT("pixas not defined", procName, 1);
2724  if (!ppixad && !pboxa)
2725  return ERROR_INT("no output requested", procName, 1);
2726 
2727  n = pixaGetCount(pixas);
2728  if (ppixad) *ppixad = pixaCreate(n);
2729  if (pboxa) *pboxa = boxaCreate(n);
2730  for (i = 0; i < n; i++) {
2731  pix1 = pixaGetPix(pixas, i, L_CLONE);
2732  pixClipToForeground(pix1, &pix2, &box1);
2733  pixDestroy(&pix1);
2734  if (ppixad)
2735  pixaAddPix(*ppixad, pix2, L_INSERT);
2736  else
2737  pixDestroy(&pix2);
2738  if (pboxa)
2739  boxaAddBox(*pboxa, box1, L_INSERT);
2740  else
2741  boxDestroy(&box1);
2742  }
2743 
2744  return 0;
2745 }
2746 
2747 
2766 l_ok
2768  l_int32 *pdepth)
2769 {
2770 l_int32 hascolor, maxdepth;
2771 
2772  PROCNAME("pixaGetRenderingDepth");
2773 
2774  if (!pdepth)
2775  return ERROR_INT("&depth not defined", procName, 1);
2776  *pdepth = 0;
2777  if (!pixa)
2778  return ERROR_INT("pixa not defined", procName, 1);
2779 
2780  pixaHasColor(pixa, &hascolor);
2781  if (hascolor) {
2782  *pdepth = 32;
2783  return 0;
2784  }
2785 
2786  pixaGetDepthInfo(pixa, &maxdepth, NULL);
2787  if (maxdepth == 1)
2788  *pdepth = 1;
2789  else /* 2, 4, 8 or 16 */
2790  *pdepth = 8;
2791  return 0;
2792 }
2793 
2794 
2803 l_ok
2805  l_int32 *phascolor)
2806 {
2807 l_int32 i, n, hascolor, d;
2808 PIX *pix;
2809 PIXCMAP *cmap;
2810 
2811  PROCNAME("pixaHasColor");
2812 
2813  if (!phascolor)
2814  return ERROR_INT("&hascolor not defined", procName, 1);
2815  *phascolor = 0;
2816  if (!pixa)
2817  return ERROR_INT("pixa not defined", procName, 1);
2818 
2819  n = pixaGetCount(pixa);
2820  hascolor = 0;
2821  for (i = 0; i < n; i++) {
2822  pix = pixaGetPix(pixa, i, L_CLONE);
2823  if ((cmap = pixGetColormap(pix)) != NULL)
2824  pixcmapHasColor(cmap, &hascolor);
2825  d = pixGetDepth(pix);
2826  pixDestroy(&pix);
2827  if (d == 32 || hascolor == 1) {
2828  *phascolor = 1;
2829  break;
2830  }
2831  }
2832 
2833  return 0;
2834 }
2835 
2836 
2844 l_ok
2846  l_int32 *phascmap)
2847 {
2848 l_int32 i, n;
2849 PIX *pix;
2850 PIXCMAP *cmap;
2851 
2852  PROCNAME("pixaAnyColormaps");
2853 
2854  if (!phascmap)
2855  return ERROR_INT("&hascmap not defined", procName, 1);
2856  *phascmap = 0;
2857  if (!pixa)
2858  return ERROR_INT("pixa not defined", procName, 1);
2859 
2860  n = pixaGetCount(pixa);
2861  for (i = 0; i < n; i++) {
2862  pix = pixaGetPix(pixa, i, L_CLONE);
2863  cmap = pixGetColormap(pix);
2864  pixDestroy(&pix);
2865  if (cmap) {
2866  *phascmap = 1;
2867  return 0;
2868  }
2869  }
2870 
2871  return 0;
2872 }
2873 
2874 
2883 l_ok
2885  l_int32 *pmaxdepth,
2886  l_int32 *psame)
2887 {
2888 l_int32 i, n, d, d0;
2889 l_int32 maxd, same; /* depth info */
2890 
2891  PROCNAME("pixaGetDepthInfo");
2892 
2893  if (pmaxdepth) *pmaxdepth = 0;
2894  if (psame) *psame = TRUE;
2895  if (!pmaxdepth && !psame) return 0;
2896  if (!pixa)
2897  return ERROR_INT("pixa not defined", procName, 1);
2898  if ((n = pixaGetCount(pixa)) == 0)
2899  return ERROR_INT("pixa is empty", procName, 1);
2900 
2901  same = TRUE;
2902  maxd = 0;
2903  for (i = 0; i < n; i++) {
2904  pixaGetPixDimensions(pixa, i, NULL, NULL, &d);
2905  if (i == 0)
2906  d0 = d;
2907  else if (d != d0)
2908  same = FALSE;
2909  if (d > maxd) maxd = d;
2910  }
2911 
2912  if (pmaxdepth) *pmaxdepth = maxd;
2913  if (psame) *psame = same;
2914  return 0;
2915 }
2916 
2917 
2936 PIXA *
2938 {
2939 l_int32 i, n, depth, same, hascmap, maxdepth;
2940 BOXA *boxa;
2941 PIX *pix1, *pix2;
2942 PIXA *pixa1, *pixad;
2943 
2944  PROCNAME("pixaConvertToSameDepth");
2945 
2946  if (!pixas)
2947  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
2948  if ((n = pixaGetCount(pixas)) == 0)
2949  return (PIXA *)ERROR_PTR("no components", procName, NULL);
2950 
2951 
2952  /* Remove colormaps if necessary */
2953  pixaGetRenderingDepth(pixas, &depth);
2954  pixaAnyColormaps(pixas, &hascmap);
2955  if (hascmap) {
2956  pixa1 = pixaCreate(n);
2957  for (i = 0; i < n; i++) {
2958  pix1 = pixaGetPix(pixas, i, L_CLONE);
2959  if (depth == 32)
2960  pix2 = pixConvertTo32(pix1);
2961  else /* depth = 8 */
2962  pix2 = pixConvertTo8(pix1, 0);
2963  pixaAddPix(pixa1, pix2, L_INSERT);
2964  pixDestroy(&pix1);
2965  }
2966  } else {
2967  pixa1 = pixaCopy(pixas, L_CLONE);
2968  }
2969 
2970  pixaGetDepthInfo(pixa1, &maxdepth, &same);
2971  if (!same) { /* at least one pix has depth < maxdepth */
2972  pixad = pixaCreate(n);
2973  for (i = 0; i < n; i++) {
2974  pix1 = pixaGetPix(pixa1, i, L_CLONE);
2975  if (maxdepth <= 16)
2976  pix2 = pixConvertTo8(pix1, 0);
2977  else
2978  pix2 = pixConvertTo32(pix1);
2979  pixaAddPix(pixad, pix2, L_INSERT);
2980  pixDestroy(&pix1);
2981  }
2982  } else {
2983  pixad = pixaCopy(pixa1, L_CLONE);
2984  }
2985 
2986  boxa = pixaGetBoxa(pixas, L_COPY);
2987  pixaSetBoxa(pixad, boxa, L_INSERT);
2988  pixaDestroy(&pixa1);
2989  return pixad;
2990 }
2991 
2992 
3008 PIXA *
3010  l_int32 depth)
3011 {
3012 l_int32 i, n, maxd;
3013 BOXA *boxa;
3014 PIX *pix1, *pix2;
3015 PIXA *pixad;
3016 
3017  PROCNAME("pixaConvertToGivenDepth");
3018 
3019  if (!pixas)
3020  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
3021  if ((n = pixaGetCount(pixas)) == 0)
3022  return (PIXA *)ERROR_PTR("no components", procName, NULL);
3023  if (depth != 8 && depth != 32)
3024  return (PIXA *)ERROR_PTR("depth not 8 or 32", procName, NULL);
3025 
3026  /* Warn with 1 --> {8,32} or lossy conversions */
3027  pixaGetRenderingDepth(pixas, &maxd);
3028  if (maxd == 1)
3029  L_WARNING("All pix are 1 bpp; converting to %d bpp\n", procName, depth);
3030  if (maxd > depth)
3031  L_WARNING("Lossy conversion: max rendering depth %d > input %d\n",
3032  procName, maxd, depth);
3033 
3034  pixad = pixaCreate(n);
3035  for (i = 0; i < n; i++) {
3036  pix1 = pixaGetPix(pixas, i, L_CLONE);
3037  if (depth == 32) {
3038  pix2 = (pixGetDepth(pix1) == 32) ? pixClone(pix1) :
3039  pixConvertTo32(pix1);
3040  } else { /* depth = 8 */
3041  pix2 = pixConvertTo8(pix1, 0);
3042  }
3043  pixaAddPix(pixad, pix2, L_INSERT);
3044  pixDestroy(&pix1);
3045  }
3046 
3047  boxa = pixaGetBoxa(pixas, L_COPY);
3048  pixaSetBoxa(pixad, boxa, L_INSERT);
3049  return pixad;
3050 }
3051 
3052 
3081 l_ok
3083  PIXA *pixa2,
3084  l_int32 maxdist,
3085  NUMA **pnaindex,
3086  l_int32 *psame)
3087 {
3088 l_int32 i, j, n, empty1, empty2, same, sameboxa;
3089 BOXA *boxa1, *boxa2;
3090 NUMA *na;
3091 PIX *pix1, *pix2;
3092 
3093  PROCNAME("pixaEqual");
3094 
3095  if (pnaindex) *pnaindex = NULL;
3096  if (!psame)
3097  return ERROR_INT("&same not defined", procName, 1);
3098  *psame = 0;
3099  sameboxa = 0;
3100  na = NULL;
3101  if (!pixa1 || !pixa2)
3102  return ERROR_INT("pixa1 and pixa2 not both defined", procName, 1);
3103  n = pixaGetCount(pixa1);
3104  if (n != pixaGetCount(pixa2))
3105  return 0;
3106 
3107  /* If there are no boxes, strict ordering of the pix in each
3108  * pixa is required. */
3109  boxa1 = pixaGetBoxa(pixa1, L_CLONE);
3110  boxa2 = pixaGetBoxa(pixa2, L_CLONE);
3111  empty1 = (boxaGetCount(boxa1) == 0) ? 1 : 0;
3112  empty2 = (boxaGetCount(boxa2) == 0) ? 1 : 0;
3113  if (!empty1 && !empty2) {
3114  boxaEqual(boxa1, boxa2, maxdist, &na, &sameboxa);
3115  if (!sameboxa) {
3116  boxaDestroy(&boxa1);
3117  boxaDestroy(&boxa2);
3118  numaDestroy(&na);
3119  return 0;
3120  }
3121  }
3122  boxaDestroy(&boxa1);
3123  boxaDestroy(&boxa2);
3124  if ((!empty1 && empty2) || (empty1 && !empty2))
3125  return 0;
3126 
3127  for (i = 0; i < n; i++) {
3128  pix1 = pixaGetPix(pixa1, i, L_CLONE);
3129  if (na)
3130  numaGetIValue(na, i, &j);
3131  else
3132  j = i;
3133  pix2 = pixaGetPix(pixa2, j, L_CLONE);
3134  pixEqual(pix1, pix2, &same);
3135  pixDestroy(&pix1);
3136  pixDestroy(&pix2);
3137  if (!same) {
3138  numaDestroy(&na);
3139  return 0;
3140  }
3141  }
3142 
3143  *psame = 1;
3144  if (pnaindex)
3145  *pnaindex = na;
3146  else
3147  numaDestroy(&na);
3148  return 0;
3149 }
3150 
3151 
3165 l_ok
3167 {
3168 l_int32 i, n, w, h;
3169 BOX *box;
3170 BOXA *boxa;
3171 PIX *pix;
3172 
3173  PROCNAME("pixaSetFullSizeBoxa");
3174 
3175  if (!pixa)
3176  return ERROR_INT("pixa not defined", procName, 1);
3177  if ((n = pixaGetCount(pixa)) == 0) {
3178  L_INFO("pixa contains no pix\n", procName);
3179  return 0;
3180  }
3181 
3182  boxa = boxaCreate(n);
3183  pixaSetBoxa(pixa, boxa, L_INSERT);
3184  for (i = 0; i < n; i++) {
3185  pix = pixaGetPix(pixa, i, L_CLONE);
3186  pixGetDimensions(pix, &w, &h, NULL);
3187  box = boxCreate(0, 0, w, h);
3188  boxaAddBox(boxa, box, L_INSERT);
3189  pixDestroy(&pix);
3190  }
3191  return 0;
3192 }
3193 
void boxDestroy(BOX **pbox)
boxDestroy()
Definition: boxbasic.c:282
l_ok boxaReplaceBox(BOXA *boxa, l_int32 index, BOX *box)
boxaReplaceBox()
Definition: boxbasic.c:962
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 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
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 boxaEqual(BOXA *boxa1, BOXA *boxa2, l_int32 maxdist, NUMA **pnaindex, l_int32 *psame)
boxaEqual()
Definition: boxfunc1.c:2325
BOX * boxAdjustSides(BOX *boxd, BOX *boxs, l_int32 delleft, l_int32 delright, l_int32 deltop, l_int32 delbot)
boxAdjustSides()
Definition: boxfunc1.c:1991
BOX * boxRotateOrth(BOX *box, l_int32 w, l_int32 h, l_int32 rotation)
boxRotateOrth()
Definition: boxfunc2.c:522
BOXA * boxaTransform(BOXA *boxas, l_int32 shiftx, l_int32 shifty, l_float32 scalex, l_float32 scaley)
boxaTransform()
Definition: boxfunc2.c:102
l_ok boxaGetExtent(BOXA *boxa, l_int32 *pw, l_int32 *ph, BOX **pbox)
boxaGetExtent()
Definition: boxfunc4.c:953
l_ok pixcmapHasColor(PIXCMAP *cmap, l_int32 *pcolor)
pixcmapHasColor()
Definition: colormap.c:1075
l_ok pixEqual(PIX *pix1, PIX *pix2, l_int32 *psame)
pixEqual()
Definition: compare.c:156
BOXA * pixConnComp(PIX *pixs, PIXA **ppixa, l_int32 connectivity)
pixConnComp()
Definition: conncomp.c:151
l_ok pixCountConnComp(PIX *pixs, l_int32 connectivity, l_int32 *pcount)
pixCountConnComp()
Definition: conncomp.c:394
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:478
l_int32 numaaGetNumberCount(NUMAA *naa)
numaaGetNumberCount()
Definition: numabasic.c:1670
NUMA * numaCreateFromString(const char *str)
numaCreateFromString()
Definition: numabasic.c:315
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:194
l_int32 numaaGetCount(NUMAA *naa)
numaaGetCount()
Definition: numabasic.c:1631
NUMA * numaaGetNuma(NUMAA *naa, l_int32 index, l_int32 accessflag)
numaaGetNuma()
Definition: numabasic.c:1740
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:366
l_int32 numaGetCount(NUMA *na)
numaGetCount()
Definition: numabasic.c:658
l_ok numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition: numabasic.c:754
NUMA * numaMakeThresholdIndicator(NUMA *nas, l_float32 thresh, l_int32 type)
numaMakeThresholdIndicator()
Definition: numafunc1.c:1231
NUMA * numaGetSortIndex(NUMA *na, l_int32 sortorder)
numaGetSortIndex()
Definition: numafunc1.c:2751
l_ok numaGetMax(NUMA *na, l_float32 *pmaxval, l_int32 *pimaxloc)
numaGetMax()
Definition: numafunc1.c:496
NUMA * numaGetBinSortIndex(NUMA *nas, l_int32 sortorder)
numaGetBinSortIndex()
Definition: numafunc1.c:2833
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
l_ok pixCopyColormap(PIX *pixd, const PIX *pixs)
pixCopyColormap()
Definition: pix1.c:816
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:315
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:593
PIX * pixAddBorderGeneral(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_uint32 val)
pixAddBorderGeneral()
Definition: pix2.c:1917
l_ok pixZero(PIX *pix, l_int32 *pempty)
pixZero()
Definition: pix3.c:1815
NUMA * pixaCountPixels(PIXA *pixa)
pixaCountPixels()
Definition: pix3.c:1892
PIX * pixAnd(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixAnd()
Definition: pix3.c:1624
NUMA * pixaFindAreaFraction(PIXA *pixa)
pixaFindAreaFraction()
Definition: pix5.c:441
NUMA * pixaFindPerimSizeRatio(PIXA *pixa)
pixaFindPerimSizeRatio()
Definition: pix5.c:345
NUMA * pixaFindPerimToAreaRatio(PIXA *pixa)
pixaFindPerimToAreaRatio()
Definition: pix5.c:241
PIX * pixClipRectangle(PIX *pixs, BOX *box, BOX **pboxc)
pixClipRectangle()
Definition: pix5.c:1026
NUMA * pixaFindWidthHeightRatio(PIXA *pixa)
pixaFindWidthHeightRatio()
Definition: pix5.c:670
l_ok pixClipToForeground(PIX *pixs, PIX **ppixd, BOX **pbox)
pixClipToForeground()
Definition: pix5.c:1784
#define PIX_DST
Definition: pix.h:331
@ L_SELECT_IF_LTE
Definition: pix.h:784
@ L_SELECT_IF_LT
Definition: pix.h:782
@ L_SELECT_IF_GT
Definition: pix.h:783
@ L_SELECT_IF_GTE
Definition: pix.h:785
@ L_SELECT_IF_BOTH
Definition: pix.h:806
@ L_SELECT_IF_EITHER
Definition: pix.h:804
@ L_SELECT_WIDTH
Definition: pix.h:800
@ L_SELECT_HEIGHT
Definition: pix.h:801
@ L_SORT_BY_AREA
Definition: pix.h:744
@ L_SORT_BY_MIN_DIMENSION
Definition: pix.h:741
@ L_SORT_BY_PERIMETER
Definition: pix.h:743
@ L_SORT_BY_WIDTH
Definition: pix.h:739
@ L_SORT_BY_ASPECT_RATIO
Definition: pix.h:745
@ L_SORT_BY_HEIGHT
Definition: pix.h:740
@ L_SORT_BY_MAX_DIMENSION
Definition: pix.h:742
@ L_SORT_BY_Y
Definition: pix.h:736
@ L_SORT_BY_X
Definition: pix.h:735
@ L_COPY
Definition: pix.h:712
@ L_CLONE
Definition: pix.h:713
@ L_INSERT
Definition: pix.h:711
#define PIX_SRC
Definition: pix.h:330
@ L_SORT_DECREASING
Definition: pix.h:730
@ L_SORT_INCREASING
Definition: pix.h:729
#define PIX_NOT(op)
Definition: pix.h:332
@ L_BRING_IN_BLACK
Definition: pix.h:870
@ L_BRING_IN_WHITE
Definition: pix.h:869
@ L_ROTATE_SAMPLING
Definition: pix.h:864
@ L_ROTATE_SHEAR
Definition: pix.h:863
@ L_ROTATE_AREA_MAP
Definition: pix.h:862
PIXAA * pixaaCreate(l_int32 n)
pixaaCreate()
Definition: pixabasic.c:1852
l_ok pixaAddPix(PIXA *pixa, PIX *pix, l_int32 copyflag)
pixaAddPix()
Definition: pixabasic.c:506
void pixaDestroy(PIXA **ppixa)
pixaDestroy()
Definition: pixabasic.c:412
l_ok pixaVerifyDepth(PIXA *pixa, l_int32 *psame, l_int32 *pmaxd)
pixaVerifyDepth()
Definition: pixabasic.c:960
BOX * pixaGetBox(PIXA *pixa, l_int32 index, l_int32 accesstype)
pixaGetBox()
Definition: pixabasic.c:816
l_int32 pixaGetBoxaCount(PIXA *pixa)
pixaGetBoxaCount()
Definition: pixabasic.c:784
l_ok pixaaAddPixa(PIXAA *paa, PIXA *pixa, l_int32 copyflag)
pixaaAddPixa()
Definition: pixabasic.c:1998
PIXA * pixaCreate(l_int32 n)
pixaCreate()
Definition: pixabasic.c:167
l_ok pixaGetPixDimensions(PIXA *pixa, l_int32 index, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixaGetPixDimensions()
Definition: pixabasic.c:726
PIXA * pixaCopy(PIXA *pixa, l_int32 copyflag)
pixaCopy()
Definition: pixabasic.c:453
l_ok pixaReplacePix(PIXA *pixa, l_int32 index, PIX *pix, BOX *box)
pixaReplacePix()
Definition: pixabasic.c:1320
l_int32 pixaGetCount(PIXA *pixa)
pixaGetCount()
Definition: pixabasic.c:650
l_ok pixaAddBox(PIXA *pixa, BOX *box, l_int32 copyflag)
pixaAddBox()
Definition: pixabasic.c:555
BOXA * pixaGetBoxa(PIXA *pixa, l_int32 accesstype)
pixaGetBoxa()
Definition: pixabasic.c:760
l_int32 pixaaGetCount(PIXAA *paa, NUMA **pna)
pixaaGetCount()
Definition: pixabasic.c:2157
PIXA * pixaaGetPixa(PIXAA *paa, l_int32 index, l_int32 accesstype)
pixaaGetPixa()
Definition: pixabasic.c:2206
PIX * pixaGetPix(PIXA *pixa, l_int32 index, l_int32 accesstype)
pixaGetPix()
Definition: pixabasic.c:691
l_ok pixaSetBoxa(PIXA *pixa, BOXA *boxa, l_int32 accesstype)
pixaSetBoxa()
Definition: pixabasic.c:896
PIXA * pixaSelectRange(PIXA *pixas, l_int32 first, l_int32 last, l_int32 copyflag)
pixaSelectRange()
Definition: pixafunc1.c:1809
l_ok pixaGetRenderingDepth(PIXA *pixa, l_int32 *pdepth)
pixaGetRenderingDepth()
Definition: pixafunc1.c:2767
PIXA * pixaSelectByWidthHeightRatio(PIXA *pixas, l_float32 thresh, l_int32 type, l_int32 *pchanged)
pixaSelectByWidthHeightRatio()
Definition: pixafunc1.c:1059
PIXA * pixaRotateOrth(PIXA *pixas, l_int32 rotation)
pixaRotateOrth()
Definition: pixafunc1.c:2285
l_ok pixaHasColor(PIXA *pixa, l_int32 *phascolor)
pixaHasColor()
Definition: pixafunc1.c:2804
PIXA * pixaSelectByAreaFraction(PIXA *pixas, l_float32 thresh, l_int32 type, l_int32 *pchanged)
pixaSelectByAreaFraction()
Definition: pixafunc1.c:792
PIX * pixSelectBySize(PIX *pixs, l_int32 width, l_int32 height, l_int32 connectivity, l_int32 type, l_int32 relation, l_int32 *pchanged)
pixSelectBySize()
Definition: pixafunc1.c:219
PIXA * pixaSelectByNumConnComp(PIXA *pixas, l_int32 nmin, l_int32 nmax, l_int32 connectivity, l_int32 *pchanged)
pixaSelectByNumConnComp()
Definition: pixafunc1.c:1109
PIX * pixaRenderComponent(PIX *pixs, PIXA *pixa, l_int32 index)
pixaRenderComponent()
Definition: pixafunc1.c:1405
l_ok pixaSizeRange(PIXA *pixa, l_int32 *pminw, l_int32 *pminh, l_int32 *pmaxw, l_int32 *pmaxh)
pixaSizeRange()
Definition: pixafunc1.c:2591
PIXAA * pixaSort2dByIndex(PIXA *pixas, NUMAA *naa, l_int32 copyflag)
pixaSort2dByIndex()
Definition: pixafunc1.c:1744
PIXA * pixaSelectByPerimSizeRatio(PIXA *pixas, l_float32 thresh, l_int32 type, l_int32 *pchanged)
pixaSelectByPerimSizeRatio()
Definition: pixafunc1.c:658
PIXAA * pixaaScaleToSize(PIXAA *paas, l_int32 wd, l_int32 hd)
pixaaScaleToSize()
Definition: pixafunc1.c:1925
l_ok pixaaSizeRange(PIXAA *paa, l_int32 *pminw, l_int32 *pminh, l_int32 *pmaxw, l_int32 *pmaxh)
pixaaSizeRange()
Definition: pixafunc1.c:2537
l_ok pixaSetFullSizeBoxa(PIXA *pixa)
pixaSetFullSizeBoxa()
Definition: pixafunc1.c:3166
PIXA * pixaSelectByPerimToAreaRatio(PIXA *pixas, l_float32 thresh, l_int32 type, l_int32 *pchanged)
pixaSelectByPerimToAreaRatio()
Definition: pixafunc1.c:527
PIXA * pixaSelectWithString(PIXA *pixas, const char *str, l_int32 *perror)
pixaSelectWithString()
Definition: pixafunc1.c:1334
PIX * pixSelectByAreaFraction(PIX *pixs, l_float32 thresh, l_int32 connectivity, l_int32 type, l_int32 *pchanged)
pixSelectByAreaFraction()
Definition: pixafunc1.c:714
PIXA * pixaTranslate(PIXA *pixas, l_int32 hshift, l_int32 vshift, l_int32 incolor)
pixaTranslate()
Definition: pixafunc1.c:2337
PIXAA * pixaaSelectRange(PIXAA *paas, l_int32 first, l_int32 last, l_int32 copyflag)
pixaaSelectRange()
Definition: pixafunc1.c:1864
l_ok pixaAnyColormaps(PIXA *pixa, l_int32 *phascmap)
pixaAnyColormaps()
Definition: pixafunc1.c:2845
PIX * pixSelectByPerimToAreaRatio(PIX *pixs, l_float32 thresh, l_int32 connectivity, l_int32 type, l_int32 *pchanged)
pixSelectByPerimToAreaRatio()
Definition: pixafunc1.c:453
PIXA * pixaScale(PIXA *pixas, l_float32 scalex, l_float32 scaley)
pixaScale()
Definition: pixafunc1.c:2111
l_ok pixRemoveWithIndicator(PIX *pixs, PIXA *pixa, NUMA *na)
pixRemoveWithIndicator()
Definition: pixafunc1.c:1228
PIXA * pixaConvertToGivenDepth(PIXA *pixas, l_int32 depth)
pixaConvertToGivenDepth()
Definition: pixafunc1.c:3009
PIXA * pixaScaleBySampling(PIXA *pixas, l_float32 scalex, l_float32 scaley)
pixaScaleBySampling()
Definition: pixafunc1.c:2162
l_ok pixAddWithIndicator(PIX *pixs, PIXA *pixa, NUMA *na)
pixAddWithIndicator()
Definition: pixafunc1.c:1281
PIX * pixSelectByWidthHeightRatio(PIX *pixs, l_float32 thresh, l_int32 connectivity, l_int32 type, l_int32 *pchanged)
pixSelectByWidthHeightRatio()
Definition: pixafunc1.c:981
l_ok pixaClipToForeground(PIXA *pixas, PIXA **ppixad, BOXA **pboxa)
pixaClipToForeground()
Definition: pixafunc1.c:2710
PIXA * pixaAddBorderGeneral(PIXA *pixad, PIXA *pixas, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_uint32 val)
pixaAddBorderGeneral()
Definition: pixafunc1.c:2411
l_ok pixaGetDepthInfo(PIXA *pixa, l_int32 *pmaxdepth, l_int32 *psame)
pixaGetDepthInfo()
Definition: pixafunc1.c:2884
PIXA * pixaRotate(PIXA *pixas, l_float32 angle, l_int32 type, l_int32 incolor, l_int32 width, l_int32 height)
pixaRotate()
Definition: pixafunc1.c:2227
PIXA * pixaSortByIndex(PIXA *pixas, NUMA *naindex, l_int32 copyflag)
pixaSortByIndex()
Definition: pixafunc1.c:1703
PIXA * pixaSort(PIXA *pixas, l_int32 sorttype, l_int32 sortorder, NUMA **pnaindex, l_int32 copyflag)
pixaSort()
Definition: pixafunc1.c:1475
PIXA * pixaBinSort(PIXA *pixas, l_int32 sorttype, l_int32 sortorder, NUMA **pnaindex, l_int32 copyflag)
pixaBinSort()
Definition: pixafunc1.c:1615
PIXA * pixaSelectBySize(PIXA *pixas, l_int32 width, l_int32 height, l_int32 type, l_int32 relation, l_int32 *pchanged)
pixaSelectBySize()
Definition: pixafunc1.c:306
PIXAA * pixaaScaleToSizeVar(PIXAA *paas, NUMA *nawd, NUMA *nahd)
pixaaScaleToSizeVar()
Definition: pixafunc1.c:1974
l_ok pixaEqual(PIXA *pixa1, PIXA *pixa2, l_int32 maxdist, NUMA **pnaindex, l_int32 *psame)
pixaEqual()
Definition: pixafunc1.c:3082
PIXA * pixaClipToPix(PIXA *pixas, PIX *pixs)
pixaClipToPix()
Definition: pixafunc1.c:2661
PIXA * pixaSelectByArea(PIXA *pixas, l_float32 thresh, l_int32 type, l_int32 *pchanged)
pixaSelectByArea()
Definition: pixafunc1.c:926
PIXA * pixaScaleToSize(PIXA *pixas, l_int32 wd, l_int32 hd)
pixaScaleToSize()
Definition: pixafunc1.c:2022
PIXA * pixaaFlattenToPixa(PIXAA *paa, NUMA **pnaindex, l_int32 copyflag)
pixaaFlattenToPixa()
Definition: pixafunc1.c:2482
PIXA * pixaScaleToSizeRel(PIXA *pixas, l_int32 delw, l_int32 delh)
pixaScaleToSizeRel()
Definition: pixafunc1.c:2067
PIXA * pixaSelectWithIndicator(PIXA *pixas, NUMA *na, l_int32 *pchanged)
pixaSelectWithIndicator()
Definition: pixafunc1.c:1168
PIXA * pixaConvertToSameDepth(PIXA *pixas)
pixaConvertToSameDepth()
Definition: pixafunc1.c:2937
NUMA * pixaMakeSizeIndicator(PIXA *pixa, l_int32 width, l_int32 height, l_int32 type, l_int32 relation)
pixaMakeSizeIndicator()
Definition: pixafunc1.c:362
PIX * pixSelectByPerimSizeRatio(PIX *pixs, l_float32 thresh, l_int32 connectivity, l_int32 type, l_int32 *pchanged)
pixSelectByPerimSizeRatio()
Definition: pixafunc1.c:584
PIX * pixSelectByArea(PIX *pixs, l_float32 thresh, l_int32 connectivity, l_int32 type, l_int32 *pchanged)
pixSelectByArea()
Definition: pixafunc1.c:848
PIX * pixaDisplay(PIXA *pixa, l_int32 w, l_int32 h)
pixaDisplay()
Definition: pixafunc2.c:191
PIX * pixConvertTo8(PIX *pixs, l_int32 cmapflag)
pixConvertTo8()
Definition: pixconv.c:3133
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3332
PIX * pixTranslate(PIX *pixd, PIX *pixs, l_int32 hshift, l_int32 vshift, l_int32 incolor)
pixTranslate()
Definition: rop.c:445
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
PIX * pixRotate(PIX *pixs, l_float32 angle, l_int32 type, l_int32 incolor, l_int32 width, l_int32 height)
pixRotate()
Definition: rotate.c:101
PIX * pixRotateOrth(PIX *pixs, l_int32 quads)
pixRotateOrth()
Definition: rotateorth.c:75
PIX * pixScale(PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScale()
Definition: scale1.c:250
PIX * pixScaleToSizeRel(PIX *pixs, l_int32 delw, l_int32 delh)
pixScaleToSizeRel()
Definition: scale1.c:280
PIX * pixScaleToSize(PIX *pixs, l_int32 wd, l_int32 hd)
pixScaleToSize()
Definition: scale1.c:323
PIX * pixScaleBySampling(PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScaleBySampling()
Definition: scale1.c:1338
Definition: pix.h:481
Definition: pix.h:492
Definition: array.h:71
Definition: array.h:83
Definition: pix.h:139
Definition: pix.h:456
struct Boxa * boxa
Definition: pix.h:461
Definition: pix.h:467