Leptonica  1.77.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 
92 #include <string.h>
93 #include "allheaders.h"
94 
95  /* For more than this number of c.c. in a binarized image of
96  * semi-perimeter (w + h) about 5000 or less, the O(n) binsort
97  * is faster than the O(nlogn) shellsort. */
98 static const l_int32 MIN_COMPS_FOR_BIN_SORT = 200;
99 
100  /* Don't rotate any angle smaller than this */
101 static const l_float32 MIN_ANGLE_TO_ROTATE = 0.001; /* radians; ~0.06 deg */
102 
103 
104 /*---------------------------------------------------------------------*
105  * Filters *
106  *---------------------------------------------------------------------*/
107 /*
108  * These filters work on the connected components of 1 bpp images.
109  * They are typically used on pixa that have been generated from a Pix
110  * using pixConnComp(), so that the corresponding Boxa is available.
111  *
112  * The filters remove or retain c.c. based on these properties:
113  * (a) size [pixaFindDimensions()]
114  * (b) area-to-perimeter ratio [pixaFindAreaPerimRatio()]
115  * (c) foreground area as a fraction of bounding box area (w * h)
116  * [pixaFindForegroundArea()]
117  * (d) number of foreground pixels [pixaCountPixels()]
118  * (e) width/height aspect ratio [pixFindWidthHeightRatio()]
119  *
120  * We provide two different high-level interfaces:
121  * (1) Functions that use one of the filters on either
122  * a pix or the pixa of components.
123  * (2) A general method that generates numas of indicator functions,
124  * logically combines them, and efficiently removes or adds
125  * the selected components.
126  *
127  * For interface (1), the filtering is performed with a single function call.
128  * This is the easiest way to do simple filtering. These functions
129  * are named pixSelectBy*() and pixaSelectBy*(), where the '*' is one of:
130  * Size
131  * PerimToAreaRatio
132  * PerimSizeRatio
133  * AreaFraction
134  * WidthHeightRatio
135  *
136  * For more complicated filtering, use the general method (2).
137  * The numa indicator functions for a pixa are generated by these functions:
138  * pixaFindDimensions()
139  * pixaFindPerimToAreaRatio()
140  * pixaFindPerimSizeRatio()
141  * pixaFindAreaFraction()
142  * pixaCountPixels()
143  * pixaFindWidthHeightRatio()
144  * pixaFindWidthHeightProduct()
145  *
146  * Here is an illustration using the general method. Suppose you want
147  * all 8-connected components that have a height greater than 40 pixels,
148  * a width not more than 30 pixels, between 150 and 300 fg pixels,
149  * and a perimeter-to-size ratio between 1.2 and 2.0.
150  *
151  * // Generate the pixa of 8 cc pieces.
152  * boxa = pixConnComp(pixs, &pixa, 8);
153  *
154  * // Extract the data we need about each component.
155  * pixaFindDimensions(pixa, &naw, &nah);
156  * nas = pixaCountPixels(pixa);
157  * nar = pixaFindPerimSizeRatio(pixa);
158  *
159  * // Build the indicator arrays for the set of components,
160  * // based on thresholds and selection criteria.
161  * na1 = numaMakeThresholdIndicator(nah, 40, L_SELECT_IF_GT);
162  * na2 = numaMakeThresholdIndicator(naw, 30, L_SELECT_IF_LTE);
163  * na3 = numaMakeThresholdIndicator(nas, 150, L_SELECT_IF_GTE);
164  * na4 = numaMakeThresholdIndicator(nas, 300, L_SELECT_IF_LTE);
165  * na5 = numaMakeThresholdIndicator(nar, 1.2, L_SELECT_IF_GTE);
166  * na6 = numaMakeThresholdIndicator(nar, 2.0, L_SELECT_IF_LTE);
167  *
168  * // Combine the indicator arrays logically to find
169  * // the components that will be retained.
170  * nad = numaLogicalOp(NULL, na1, na2, L_INTERSECTION);
171  * numaLogicalOp(nad, nad, na3, L_INTERSECTION);
172  * numaLogicalOp(nad, nad, na4, L_INTERSECTION);
173  * numaLogicalOp(nad, nad, na5, L_INTERSECTION);
174  * numaLogicalOp(nad, nad, na6, L_INTERSECTION);
175  *
176  * // Invert to get the components that will be removed.
177  * numaInvert(nad, nad);
178  *
179  * // Remove the components, in-place.
180  * pixRemoveWithIndicator(pixs, pixa, nad);
181  */
182 
183 
211 PIX *
213  l_int32 width,
214  l_int32 height,
215  l_int32 connectivity,
216  l_int32 type,
217  l_int32 relation,
218  l_int32 *pchanged)
219 {
220 l_int32 w, h, empty, changed, count;
221 BOXA *boxa;
222 PIX *pixd;
223 PIXA *pixas, *pixad;
224 
225  PROCNAME("pixSelectBySize");
226 
227  if (!pixs)
228  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
229  if (connectivity != 4 && connectivity != 8)
230  return (PIX *)ERROR_PTR("connectivity not 4 or 8", procName, NULL);
231  if (type != L_SELECT_WIDTH && type != L_SELECT_HEIGHT &&
232  type != L_SELECT_IF_EITHER && type != L_SELECT_IF_BOTH)
233  return (PIX *)ERROR_PTR("invalid type", procName, NULL);
234  if (relation != L_SELECT_IF_LT && relation != L_SELECT_IF_GT &&
235  relation != L_SELECT_IF_LTE && relation != L_SELECT_IF_GTE)
236  return (PIX *)ERROR_PTR("invalid relation", procName, NULL);
237  if (pchanged) *pchanged = FALSE;
238 
239  /* Check if any components exist */
240  pixZero(pixs, &empty);
241  if (empty)
242  return pixCopy(NULL, pixs);
243 
244  /* Identify and select the components */
245  boxa = pixConnComp(pixs, &pixas, connectivity);
246  pixad = pixaSelectBySize(pixas, width, height, type, relation, &changed);
247  boxaDestroy(&boxa);
248  pixaDestroy(&pixas);
249 
250  if (!changed) {
251  pixaDestroy(&pixad);
252  return pixCopy(NULL, pixs);
253  }
254 
255  /* Render the result */
256  if (pchanged) *pchanged = TRUE;
257  pixGetDimensions(pixs, &w, &h, NULL);
258  count = pixaGetCount(pixad);
259  if (count == 0) { /* return empty pix */
260  pixd = pixCreateTemplate(pixs);
261  } else {
262  pixd = pixaDisplay(pixad, w, h);
263  pixCopyResolution(pixd, pixs);
264  pixCopyColormap(pixd, pixs);
265  pixCopyText(pixd, pixs);
266  pixCopyInputFormat(pixd, pixs);
267  }
268  pixaDestroy(&pixad);
269  return pixd;
270 }
271 
272 
298 PIXA *
300  l_int32 width,
301  l_int32 height,
302  l_int32 type,
303  l_int32 relation,
304  l_int32 *pchanged)
305 {
306 NUMA *na;
307 PIXA *pixad;
308 
309  PROCNAME("pixaSelectBySize");
310 
311  if (!pixas)
312  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
313  if (type != L_SELECT_WIDTH && type != L_SELECT_HEIGHT &&
314  type != L_SELECT_IF_EITHER && type != L_SELECT_IF_BOTH)
315  return (PIXA *)ERROR_PTR("invalid type", procName, NULL);
316  if (relation != L_SELECT_IF_LT && relation != L_SELECT_IF_GT &&
317  relation != L_SELECT_IF_LTE && relation != L_SELECT_IF_GTE)
318  return (PIXA *)ERROR_PTR("invalid relation", procName, NULL);
319 
320  /* Compute the indicator array for saving components */
321  na = pixaMakeSizeIndicator(pixas, width, height, type, relation);
322 
323  /* Filter to get output */
324  pixad = pixaSelectWithIndicator(pixas, na, pchanged);
325 
326  numaDestroy(&na);
327  return pixad;
328 }
329 
330 
354 NUMA *
356  l_int32 width,
357  l_int32 height,
358  l_int32 type,
359  l_int32 relation)
360 {
361 l_int32 i, n, w, h, ival;
362 NUMA *na;
363 
364  PROCNAME("pixaMakeSizeIndicator");
365 
366  if (!pixa)
367  return (NUMA *)ERROR_PTR("pixa not defined", procName, NULL);
368  if (type != L_SELECT_WIDTH && type != L_SELECT_HEIGHT &&
369  type != L_SELECT_IF_EITHER && type != L_SELECT_IF_BOTH)
370  return (NUMA *)ERROR_PTR("invalid type", procName, NULL);
371  if (relation != L_SELECT_IF_LT && relation != L_SELECT_IF_GT &&
372  relation != L_SELECT_IF_LTE && relation != L_SELECT_IF_GTE)
373  return (NUMA *)ERROR_PTR("invalid relation", procName, NULL);
374 
375  n = pixaGetCount(pixa);
376  na = numaCreate(n);
377  for (i = 0; i < n; i++) {
378  ival = 0;
379  pixaGetPixDimensions(pixa, i, &w, &h, NULL);
380  switch (type)
381  {
382  case L_SELECT_WIDTH:
383  if ((relation == L_SELECT_IF_LT && w < width) ||
384  (relation == L_SELECT_IF_GT && w > width) ||
385  (relation == L_SELECT_IF_LTE && w <= width) ||
386  (relation == L_SELECT_IF_GTE && w >= width))
387  ival = 1;
388  break;
389  case L_SELECT_HEIGHT:
390  if ((relation == L_SELECT_IF_LT && h < height) ||
391  (relation == L_SELECT_IF_GT && h > height) ||
392  (relation == L_SELECT_IF_LTE && h <= height) ||
393  (relation == L_SELECT_IF_GTE && h >= height))
394  ival = 1;
395  break;
396  case L_SELECT_IF_EITHER:
397  if (((relation == L_SELECT_IF_LT) && (w < width || h < height)) ||
398  ((relation == L_SELECT_IF_GT) && (w > width || h > height)) ||
399  ((relation == L_SELECT_IF_LTE) && (w <= width || h <= height)) ||
400  ((relation == L_SELECT_IF_GTE) && (w >= width || h >= height)))
401  ival = 1;
402  break;
403  case L_SELECT_IF_BOTH:
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  default:
411  L_WARNING("can't get here!\n", procName);
412  break;
413  }
414  numaAddNumber(na, ival);
415  }
416 
417  return na;
418 }
419 
420 
445 PIX *
447  l_float32 thresh,
448  l_int32 connectivity,
449  l_int32 type,
450  l_int32 *pchanged)
451 {
452 l_int32 w, h, empty, changed, count;
453 BOXA *boxa;
454 PIX *pixd;
455 PIXA *pixas, *pixad;
456 
457  PROCNAME("pixSelectByPerimToAreaRatio");
458 
459  if (!pixs)
460  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
461  if (connectivity != 4 && connectivity != 8)
462  return (PIX *)ERROR_PTR("connectivity not 4 or 8", procName, NULL);
463  if (type != L_SELECT_IF_LT && type != L_SELECT_IF_GT &&
464  type != L_SELECT_IF_LTE && type != L_SELECT_IF_GTE)
465  return (PIX *)ERROR_PTR("invalid type", procName, NULL);
466  if (pchanged) *pchanged = FALSE;
467 
468  /* Check if any components exist */
469  pixZero(pixs, &empty);
470  if (empty)
471  return pixCopy(NULL, pixs);
472 
473  /* Filter thin components */
474  boxa = pixConnComp(pixs, &pixas, connectivity);
475  pixad = pixaSelectByPerimToAreaRatio(pixas, thresh, type, &changed);
476  boxaDestroy(&boxa);
477  pixaDestroy(&pixas);
478 
479  if (!changed) {
480  pixaDestroy(&pixad);
481  return pixCopy(NULL, pixs);
482  }
483 
484  /* Render the result */
485  if (pchanged) *pchanged = TRUE;
486  pixGetDimensions(pixs, &w, &h, NULL);
487  count = pixaGetCount(pixad);
488  if (count == 0) { /* return empty pix */
489  pixd = pixCreateTemplate(pixs);
490  } else {
491  pixd = pixaDisplay(pixad, w, h);
492  pixCopyResolution(pixd, pixs);
493  pixCopyColormap(pixd, pixs);
494  pixCopyText(pixd, pixs);
495  pixCopyInputFormat(pixd, pixs);
496  }
497  pixaDestroy(&pixad);
498  return pixd;
499 }
500 
501 
519 PIXA *
521  l_float32 thresh,
522  l_int32 type,
523  l_int32 *pchanged)
524 {
525 NUMA *na, *nai;
526 PIXA *pixad;
527 
528  PROCNAME("pixaSelectByPerimToAreaRatio");
529 
530  if (!pixas)
531  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
532  if (type != L_SELECT_IF_LT && type != L_SELECT_IF_GT &&
533  type != L_SELECT_IF_LTE && type != L_SELECT_IF_GTE)
534  return (PIXA *)ERROR_PTR("invalid type", procName, NULL);
535 
536  /* Compute component ratios. */
537  na = pixaFindPerimToAreaRatio(pixas);
538 
539  /* Generate indicator array for elements to be saved. */
540  nai = numaMakeThresholdIndicator(na, thresh, type);
541  numaDestroy(&na);
542 
543  /* Filter to get output */
544  pixad = pixaSelectWithIndicator(pixas, nai, pchanged);
545 
546  numaDestroy(&nai);
547  return pixad;
548 }
549 
550 
576 PIX *
578  l_float32 thresh,
579  l_int32 connectivity,
580  l_int32 type,
581  l_int32 *pchanged)
582 {
583 l_int32 w, h, empty, changed, count;
584 BOXA *boxa;
585 PIX *pixd;
586 PIXA *pixas, *pixad;
587 
588  PROCNAME("pixSelectByPerimSizeRatio");
589 
590  if (!pixs)
591  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
592  if (connectivity != 4 && connectivity != 8)
593  return (PIX *)ERROR_PTR("connectivity not 4 or 8", procName, NULL);
594  if (type != L_SELECT_IF_LT && type != L_SELECT_IF_GT &&
595  type != L_SELECT_IF_LTE && type != L_SELECT_IF_GTE)
596  return (PIX *)ERROR_PTR("invalid type", procName, NULL);
597  if (pchanged) *pchanged = FALSE;
598 
599  /* Check if any components exist */
600  pixZero(pixs, &empty);
601  if (empty)
602  return pixCopy(NULL, pixs);
603 
604  /* Filter thin components */
605  boxa = pixConnComp(pixs, &pixas, connectivity);
606  pixad = pixaSelectByPerimSizeRatio(pixas, thresh, type, &changed);
607  boxaDestroy(&boxa);
608  pixaDestroy(&pixas);
609 
610  if (!changed) {
611  pixaDestroy(&pixad);
612  return pixCopy(NULL, pixs);
613  }
614 
615  /* Render the result */
616  if (pchanged) *pchanged = TRUE;
617  pixGetDimensions(pixs, &w, &h, NULL);
618  count = pixaGetCount(pixad);
619  if (count == 0) { /* return empty pix */
620  pixd = pixCreateTemplate(pixs);
621  } else {
622  pixd = pixaDisplay(pixad, w, h);
623  pixCopyResolution(pixd, pixs);
624  pixCopyColormap(pixd, pixs);
625  pixCopyText(pixd, pixs);
626  pixCopyInputFormat(pixd, pixs);
627  }
628  pixaDestroy(&pixad);
629  return pixd;
630 }
631 
632 
650 PIXA *
652  l_float32 thresh,
653  l_int32 type,
654  l_int32 *pchanged)
655 {
656 NUMA *na, *nai;
657 PIXA *pixad;
658 
659  PROCNAME("pixaSelectByPerimSizeRatio");
660 
661  if (!pixas)
662  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
663  if (type != L_SELECT_IF_LT && type != L_SELECT_IF_GT &&
664  type != L_SELECT_IF_LTE && type != L_SELECT_IF_GTE)
665  return (PIXA *)ERROR_PTR("invalid type", procName, NULL);
666 
667  /* Compute component ratios. */
668  na = pixaFindPerimSizeRatio(pixas);
669 
670  /* Generate indicator array for elements to be saved. */
671  nai = numaMakeThresholdIndicator(na, thresh, type);
672  numaDestroy(&na);
673 
674  /* Filter to get output */
675  pixad = pixaSelectWithIndicator(pixas, nai, pchanged);
676 
677  numaDestroy(&nai);
678  return pixad;
679 }
680 
681 
706 PIX *
708  l_float32 thresh,
709  l_int32 connectivity,
710  l_int32 type,
711  l_int32 *pchanged)
712 {
713 l_int32 w, h, empty, changed, count;
714 BOXA *boxa;
715 PIX *pixd;
716 PIXA *pixas, *pixad;
717 
718  PROCNAME("pixSelectByAreaFraction");
719 
720  if (!pixs)
721  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
722  if (connectivity != 4 && connectivity != 8)
723  return (PIX *)ERROR_PTR("connectivity not 4 or 8", procName, NULL);
724  if (type != L_SELECT_IF_LT && type != L_SELECT_IF_GT &&
725  type != L_SELECT_IF_LTE && type != L_SELECT_IF_GTE)
726  return (PIX *)ERROR_PTR("invalid type", procName, NULL);
727  if (pchanged) *pchanged = FALSE;
728 
729  /* Check if any components exist */
730  pixZero(pixs, &empty);
731  if (empty)
732  return pixCopy(NULL, pixs);
733 
734  /* Filter components */
735  boxa = pixConnComp(pixs, &pixas, connectivity);
736  pixad = pixaSelectByAreaFraction(pixas, thresh, type, &changed);
737  boxaDestroy(&boxa);
738  pixaDestroy(&pixas);
739 
740  if (!changed) {
741  pixaDestroy(&pixad);
742  return pixCopy(NULL, pixs);
743  }
744 
745  /* Render the result */
746  if (pchanged) *pchanged = TRUE;
747  pixGetDimensions(pixs, &w, &h, NULL);
748  count = pixaGetCount(pixad);
749  if (count == 0) { /* return empty pix */
750  pixd = pixCreateTemplate(pixs);
751  } else {
752  pixd = pixaDisplay(pixad, w, h);
753  pixCopyResolution(pixd, pixs);
754  pixCopyColormap(pixd, pixs);
755  pixCopyText(pixd, pixs);
756  pixCopyInputFormat(pixd, pixs);
757  }
758  pixaDestroy(&pixad);
759  return pixd;
760 }
761 
762 
784 PIXA *
786  l_float32 thresh,
787  l_int32 type,
788  l_int32 *pchanged)
789 {
790 NUMA *na, *nai;
791 PIXA *pixad;
792 
793  PROCNAME("pixaSelectByAreaFraction");
794 
795  if (!pixas)
796  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
797  if (type != L_SELECT_IF_LT && type != L_SELECT_IF_GT &&
798  type != L_SELECT_IF_LTE && type != L_SELECT_IF_GTE)
799  return (PIXA *)ERROR_PTR("invalid type", procName, NULL);
800 
801  /* Compute component ratios. */
802  na = pixaFindAreaFraction(pixas);
803 
804  /* Generate indicator array for elements to be saved. */
805  nai = numaMakeThresholdIndicator(na, thresh, type);
806  numaDestroy(&na);
807 
808  /* Filter to get output */
809  pixad = pixaSelectWithIndicator(pixas, nai, pchanged);
810 
811  numaDestroy(&nai);
812  return pixad;
813 }
814 
815 
839 PIX *
841  l_float32 thresh,
842  l_int32 connectivity,
843  l_int32 type,
844  l_int32 *pchanged)
845 {
846 l_int32 w, h, empty, changed, count;
847 BOXA *boxa;
848 PIX *pixd;
849 PIXA *pixas, *pixad;
850 
851  PROCNAME("pixSelectByWidthHeightRatio");
852 
853  if (!pixs)
854  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
855  if (connectivity != 4 && connectivity != 8)
856  return (PIX *)ERROR_PTR("connectivity not 4 or 8", procName, NULL);
857  if (type != L_SELECT_IF_LT && type != L_SELECT_IF_GT &&
858  type != L_SELECT_IF_LTE && type != L_SELECT_IF_GTE)
859  return (PIX *)ERROR_PTR("invalid type", procName, NULL);
860  if (pchanged) *pchanged = FALSE;
861 
862  /* Check if any components exist */
863  pixZero(pixs, &empty);
864  if (empty)
865  return pixCopy(NULL, pixs);
866 
867  /* Filter components */
868  boxa = pixConnComp(pixs, &pixas, connectivity);
869  pixad = pixaSelectByWidthHeightRatio(pixas, thresh, type, &changed);
870  boxaDestroy(&boxa);
871  pixaDestroy(&pixas);
872 
873  if (!changed) {
874  pixaDestroy(&pixad);
875  return pixCopy(NULL, pixs);
876  }
877 
878  /* Render the result */
879  if (pchanged) *pchanged = TRUE;
880  pixGetDimensions(pixs, &w, &h, NULL);
881  count = pixaGetCount(pixad);
882  if (count == 0) { /* return empty pix */
883  pixd = pixCreateTemplate(pixs);
884  } else {
885  pixd = pixaDisplay(pixad, w, h);
886  pixCopyResolution(pixd, pixs);
887  pixCopyColormap(pixd, pixs);
888  pixCopyText(pixd, pixs);
889  pixCopyInputFormat(pixd, pixs);
890  }
891  pixaDestroy(&pixad);
892  return pixd;
893 }
894 
895 
917 PIXA *
919  l_float32 thresh,
920  l_int32 type,
921  l_int32 *pchanged)
922 {
923 NUMA *na, *nai;
924 PIXA *pixad;
925 
926  PROCNAME("pixaSelectByWidthHeightRatio");
927 
928  if (!pixas)
929  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
930  if (type != L_SELECT_IF_LT && type != L_SELECT_IF_GT &&
931  type != L_SELECT_IF_LTE && type != L_SELECT_IF_GTE)
932  return (PIXA *)ERROR_PTR("invalid type", procName, NULL);
933 
934  /* Compute component ratios. */
935  na = pixaFindWidthHeightRatio(pixas);
936 
937  /* Generate indicator array for elements to be saved. */
938  nai = numaMakeThresholdIndicator(na, thresh, type);
939  numaDestroy(&na);
940 
941  /* Filter to get output */
942  pixad = pixaSelectWithIndicator(pixas, nai, pchanged);
943 
944  numaDestroy(&nai);
945  return pixad;
946 }
947 
948 
967 PIXA *
969  l_int32 nmin,
970  l_int32 nmax,
971  l_int32 connectivity,
972  l_int32 *pchanged)
973 {
974 l_int32 n, i, count;
975 NUMA *na;
976 PIX *pix;
977 PIXA *pixad;
978 
979  PROCNAME("pixaSelectByNumConnComp");
980 
981  if (pchanged) *pchanged = 0;
982  if (!pixas)
983  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
984  if (nmin > nmax)
985  return (PIXA *)ERROR_PTR("nmin > nmax", procName, NULL);
986  if (connectivity != 4 && connectivity != 8)
987  return (PIXA *)ERROR_PTR("connectivity not 4 or 8", procName, NULL);
988 
989  /* Get indicator array based on number of c.c. */
990  n = pixaGetCount(pixas);
991  na = numaCreate(n);
992  for (i = 0; i < n; i++) {
993  pix = pixaGetPix(pixas, i, L_CLONE);
994  pixCountConnComp(pix, connectivity, &count);
995  if (count >= nmin && count <= nmax)
996  numaAddNumber(na, 1);
997  else
998  numaAddNumber(na, 0);
999  pixDestroy(&pix);
1000  }
1001 
1002  /* Filter to get output */
1003  pixad = pixaSelectWithIndicator(pixas, na, pchanged);
1004  numaDestroy(&na);
1005  return pixad;
1006 }
1007 
1008 
1026 PIXA *
1028  NUMA *na,
1029  l_int32 *pchanged)
1030 {
1031 l_int32 i, n, nbox, ival, nsave;
1032 BOX *box;
1033 PIX *pix1;
1034 PIXA *pixad;
1035 
1036  PROCNAME("pixaSelectWithIndicator");
1037 
1038  if (!pixas)
1039  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1040  if (!na)
1041  return (PIXA *)ERROR_PTR("na not defined", procName, NULL);
1042 
1043  nsave = 0;
1044  n = numaGetCount(na);
1045  for (i = 0; i < n; i++) {
1046  numaGetIValue(na, i, &ival);
1047  if (ival == 1) nsave++;
1048  }
1049 
1050  if (nsave == n) {
1051  if (pchanged) *pchanged = FALSE;
1052  return pixaCopy(pixas, L_CLONE);
1053  }
1054  if (pchanged) *pchanged = TRUE;
1055  pixad = pixaCreate(nsave);
1056  nbox = pixaGetBoxaCount(pixas);
1057  for (i = 0; i < n; i++) {
1058  numaGetIValue(na, i, &ival);
1059  if (ival == 0) continue;
1060  pix1 = pixaGetPix(pixas, i, L_CLONE);
1061  pixaAddPix(pixad, pix1, L_INSERT);
1062  if (nbox == n) { /* fully populated boxa */
1063  box = pixaGetBox(pixas, i, L_CLONE);
1064  pixaAddBox(pixad, box, L_INSERT);
1065  }
1066  }
1067 
1068  return pixad;
1069 }
1070 
1071 
1086 l_ok
1088  PIXA *pixa,
1089  NUMA *na)
1090 {
1091 l_int32 i, n, ival, x, y, w, h;
1092 BOX *box;
1093 PIX *pix;
1094 
1095  PROCNAME("pixRemoveWithIndicator");
1096 
1097  if (!pixs)
1098  return ERROR_INT("pixs not defined", procName, 1);
1099  if (!pixa)
1100  return ERROR_INT("pixa not defined", procName, 1);
1101  if (!na)
1102  return ERROR_INT("na not defined", procName, 1);
1103  n = pixaGetCount(pixa);
1104  if (n != numaGetCount(na))
1105  return ERROR_INT("pixa and na sizes not equal", procName, 1);
1106 
1107  for (i = 0; i < n; i++) {
1108  numaGetIValue(na, i, &ival);
1109  if (ival == 1) {
1110  pix = pixaGetPix(pixa, i, L_CLONE);
1111  box = pixaGetBox(pixa, i, L_CLONE);
1112  boxGetGeometry(box, &x, &y, &w, &h);
1113  pixRasterop(pixs, x, y, w, h, PIX_DST & PIX_NOT(PIX_SRC),
1114  pix, 0, 0);
1115  boxDestroy(&box);
1116  pixDestroy(&pix);
1117  }
1118  }
1119 
1120  return 0;
1121 }
1122 
1123 
1139 l_ok
1141  PIXA *pixa,
1142  NUMA *na)
1143 {
1144 l_int32 i, n, ival, x, y, w, h;
1145 BOX *box;
1146 PIX *pix;
1147 
1148  PROCNAME("pixAddWithIndicator");
1149 
1150  if (!pixs)
1151  return ERROR_INT("pixs not defined", procName, 1);
1152  if (!pixa)
1153  return ERROR_INT("pixa not defined", procName, 1);
1154  if (!na)
1155  return ERROR_INT("na not defined", procName, 1);
1156  n = pixaGetCount(pixa);
1157  if (n != numaGetCount(na))
1158  return ERROR_INT("pixa and na sizes not equal", procName, 1);
1159 
1160  for (i = 0; i < n; i++) {
1161  numaGetIValue(na, i, &ival);
1162  if (ival == 1) {
1163  pix = pixaGetPix(pixa, i, L_CLONE);
1164  box = pixaGetBox(pixa, i, L_CLONE);
1165  boxGetGeometry(box, &x, &y, &w, &h);
1166  pixRasterop(pixs, x, y, w, h, PIX_SRC | PIX_DST, pix, 0, 0);
1167  boxDestroy(&box);
1168  pixDestroy(&pix);
1169  }
1170  }
1171 
1172  return 0;
1173 }
1174 
1175 
1192 PIXA *
1194  const char *str,
1195  l_int32 *perror)
1196 {
1197 l_int32 i, nval, npix, nbox, val, imaxval;
1198 l_float32 maxval;
1199 BOX *box;
1200 NUMA *na;
1201 PIX *pix1;
1202 PIXA *pixad;
1203 
1204  PROCNAME("pixaSelectWithString");
1205 
1206  if (perror) *perror = 0;
1207  if (!pixas)
1208  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1209  if (!str)
1210  return (PIXA *)ERROR_PTR("str not defined", procName, NULL);
1211 
1212  if ((na = numaCreateFromString(str)) == NULL)
1213  return (PIXA *)ERROR_PTR("na not made", procName, NULL);
1214  if ((nval = numaGetCount(na)) == 0) {
1215  numaDestroy(&na);
1216  return (PIXA *)ERROR_PTR("no indices found", procName, NULL);
1217  }
1218  numaGetMax(na, &maxval, NULL);
1219  imaxval = (l_int32)(maxval + 0.1);
1220  nbox = pixaGetBoxaCount(pixas);
1221  npix = pixaGetCount(pixas);
1222  if (imaxval >= npix) {
1223  if (perror) *perror = 1;
1224  L_ERROR("max index = %d, size of pixa = %d\n", procName, imaxval, npix);
1225  }
1226 
1227  pixad = pixaCreate(nval);
1228  for (i = 0; i < nval; i++) {
1229  numaGetIValue(na, i, &val);
1230  if (val < 0 || val >= npix) {
1231  L_ERROR("index %d out of range of pix\n", procName, val);
1232  continue;
1233  }
1234  pix1 = pixaGetPix(pixas, val, L_COPY);
1235  pixaAddPix(pixad, pix1, L_INSERT);
1236  if (nbox == npix) { /* fully populated boxa */
1237  box = pixaGetBox(pixas, val, L_COPY);
1238  pixaAddBox(pixad, box, L_INSERT);
1239  }
1240  }
1241  numaDestroy(&na);
1242  return pixad;
1243 }
1244 
1245 
1263 PIX *
1265  PIXA *pixa,
1266  l_int32 index)
1267 {
1268 l_int32 n, x, y, w, h, same, maxd;
1269 BOX *box;
1270 BOXA *boxa;
1271 PIX *pix;
1272 
1273  PROCNAME("pixaRenderComponent");
1274 
1275  if (!pixa)
1276  return (PIX *)ERROR_PTR("pixa not defined", procName, pixs);
1277  n = pixaGetCount(pixa);
1278  if (index < 0 || index >= n)
1279  return (PIX *)ERROR_PTR("invalid index", procName, pixs);
1280  if (pixs && (pixGetDepth(pixs) != 1))
1281  return (PIX *)ERROR_PTR("pixs not 1 bpp", procName, pixs);
1282  pixaVerifyDepth(pixa, &same, &maxd);
1283  if (maxd > 1)
1284  return (PIX *)ERROR_PTR("not all pix with d == 1", procName, pixs);
1285 
1286  boxa = pixaGetBoxa(pixa, L_CLONE);
1287  if (!pixs) {
1288  boxaGetExtent(boxa, &w, &h, NULL);
1289  pixs = pixCreate(w, h, 1);
1290  }
1291 
1292  pix = pixaGetPix(pixa, index, L_CLONE);
1293  box = boxaGetBox(boxa, index, L_CLONE);
1294  boxGetGeometry(box, &x, &y, &w, &h);
1295  pixRasterop(pixs, x, y, w, h, PIX_SRC | PIX_DST, pix, 0, 0);
1296  boxDestroy(&box);
1297  pixDestroy(&pix);
1298  boxaDestroy(&boxa);
1299 
1300  return pixs;
1301 }
1302 
1303 
1304 /*---------------------------------------------------------------------*
1305  * Sort functions *
1306  *---------------------------------------------------------------------*/
1333 PIXA *
1335  l_int32 sorttype,
1336  l_int32 sortorder,
1337  NUMA **pnaindex,
1338  l_int32 copyflag)
1339 {
1340 l_int32 i, n, nb, x, y, w, h;
1341 BOXA *boxa;
1342 NUMA *na, *naindex;
1343 PIXA *pixad;
1344 
1345  PROCNAME("pixaSort");
1346 
1347  if (pnaindex) *pnaindex = NULL;
1348  if (!pixas)
1349  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1350  if (sorttype != L_SORT_BY_X && sorttype != L_SORT_BY_Y &&
1351  sorttype != L_SORT_BY_WIDTH && sorttype != L_SORT_BY_HEIGHT &&
1352  sorttype != L_SORT_BY_MIN_DIMENSION &&
1353  sorttype != L_SORT_BY_MAX_DIMENSION &&
1354  sorttype != L_SORT_BY_PERIMETER &&
1355  sorttype != L_SORT_BY_AREA &&
1356  sorttype != L_SORT_BY_ASPECT_RATIO)
1357  return (PIXA *)ERROR_PTR("invalid sort type", procName, NULL);
1358  if (sortorder != L_SORT_INCREASING && sortorder != L_SORT_DECREASING)
1359  return (PIXA *)ERROR_PTR("invalid sort order", procName, NULL);
1360  if (copyflag != L_COPY && copyflag != L_CLONE)
1361  return (PIXA *)ERROR_PTR("invalid copy flag", procName, NULL);
1362 
1363  /* Check the pixa and boxa counts. Make a boxa if required. */
1364  if ((n = pixaGetCount(pixas)) == 0) {
1365  L_INFO("no pix in pixa\n", procName);
1366  return pixaCopy(pixas, copyflag);
1367  }
1368  if ((boxa = pixas->boxa) == NULL) /* not owned; do not destroy */
1369  return (PIXA *)ERROR_PTR("boxa not found!", procName, NULL);
1370  nb = boxaGetCount(boxa);
1371  if (nb == 0) {
1372  pixaSetFullSizeBoxa(pixas);
1373  nb = n;
1374  boxa = pixas->boxa; /* not owned */
1375  if (sorttype == L_SORT_BY_X || sorttype == L_SORT_BY_Y)
1376  L_WARNING("sort by x or y where all values are 0\n", procName);
1377  }
1378  if (nb != n)
1379  return (PIXA *)ERROR_PTR("boxa and pixa counts differ", procName, NULL);
1380 
1381  /* Use O(n) binsort if possible */
1382  if (n > MIN_COMPS_FOR_BIN_SORT &&
1383  ((sorttype == L_SORT_BY_X) || (sorttype == L_SORT_BY_Y) ||
1384  (sorttype == L_SORT_BY_WIDTH) || (sorttype == L_SORT_BY_HEIGHT) ||
1385  (sorttype == L_SORT_BY_PERIMETER)))
1386  return pixaBinSort(pixas, sorttype, sortorder, pnaindex, copyflag);
1387 
1388  /* Build up numa of specific data */
1389  if ((na = numaCreate(n)) == NULL)
1390  return (PIXA *)ERROR_PTR("na not made", procName, NULL);
1391  for (i = 0; i < n; i++) {
1392  boxaGetBoxGeometry(boxa, i, &x, &y, &w, &h);
1393  switch (sorttype)
1394  {
1395  case L_SORT_BY_X:
1396  numaAddNumber(na, x);
1397  break;
1398  case L_SORT_BY_Y:
1399  numaAddNumber(na, y);
1400  break;
1401  case L_SORT_BY_WIDTH:
1402  numaAddNumber(na, w);
1403  break;
1404  case L_SORT_BY_HEIGHT:
1405  numaAddNumber(na, h);
1406  break;
1408  numaAddNumber(na, L_MIN(w, h));
1409  break;
1411  numaAddNumber(na, L_MAX(w, h));
1412  break;
1413  case L_SORT_BY_PERIMETER:
1414  numaAddNumber(na, w + h);
1415  break;
1416  case L_SORT_BY_AREA:
1417  numaAddNumber(na, w * h);
1418  break;
1420  numaAddNumber(na, (l_float32)w / (l_float32)h);
1421  break;
1422  default:
1423  L_WARNING("invalid sort type\n", procName);
1424  }
1425  }
1426 
1427  /* Get the sort index for data array */
1428  naindex = numaGetSortIndex(na, sortorder);
1429  numaDestroy(&na);
1430  if (!naindex)
1431  return (PIXA *)ERROR_PTR("naindex not made", procName, NULL);
1432 
1433  /* Build up sorted pixa using sort index */
1434  if ((pixad = pixaSortByIndex(pixas, naindex, copyflag)) == NULL) {
1435  numaDestroy(&naindex);
1436  return (PIXA *)ERROR_PTR("pixad not made", procName, NULL);
1437  }
1438 
1439  if (pnaindex)
1440  *pnaindex = naindex;
1441  else
1442  numaDestroy(&naindex);
1443  return pixad;
1444 }
1445 
1446 
1473 PIXA *
1475  l_int32 sorttype,
1476  l_int32 sortorder,
1477  NUMA **pnaindex,
1478  l_int32 copyflag)
1479 {
1480 l_int32 i, n, x, y, w, h;
1481 BOXA *boxa;
1482 NUMA *na, *naindex;
1483 PIXA *pixad;
1484 
1485  PROCNAME("pixaBinSort");
1486 
1487  if (pnaindex) *pnaindex = NULL;
1488  if (!pixas)
1489  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1490  if (sorttype != L_SORT_BY_X && sorttype != L_SORT_BY_Y &&
1491  sorttype != L_SORT_BY_WIDTH && sorttype != L_SORT_BY_HEIGHT &&
1492  sorttype != L_SORT_BY_PERIMETER)
1493  return (PIXA *)ERROR_PTR("invalid sort type", procName, NULL);
1494  if (sortorder != L_SORT_INCREASING && sortorder != L_SORT_DECREASING)
1495  return (PIXA *)ERROR_PTR("invalid sort order", procName, NULL);
1496  if (copyflag != L_COPY && copyflag != L_CLONE)
1497  return (PIXA *)ERROR_PTR("invalid copy flag", procName, NULL);
1498 
1499  /* Verify that the pixa and its boxa have the same count */
1500  if ((boxa = pixas->boxa) == NULL) /* not owned; do not destroy */
1501  return (PIXA *)ERROR_PTR("boxa not found", procName, NULL);
1502  n = pixaGetCount(pixas);
1503  if (boxaGetCount(boxa) != n)
1504  return (PIXA *)ERROR_PTR("boxa and pixa counts differ", procName, NULL);
1505 
1506  /* Generate Numa of appropriate box dimensions */
1507  if ((na = numaCreate(n)) == NULL)
1508  return (PIXA *)ERROR_PTR("na not made", procName, NULL);
1509  for (i = 0; i < n; i++) {
1510  boxaGetBoxGeometry(boxa, i, &x, &y, &w, &h);
1511  switch (sorttype)
1512  {
1513  case L_SORT_BY_X:
1514  numaAddNumber(na, x);
1515  break;
1516  case L_SORT_BY_Y:
1517  numaAddNumber(na, y);
1518  break;
1519  case L_SORT_BY_WIDTH:
1520  numaAddNumber(na, w);
1521  break;
1522  case L_SORT_BY_HEIGHT:
1523  numaAddNumber(na, h);
1524  break;
1525  case L_SORT_BY_PERIMETER:
1526  numaAddNumber(na, w + h);
1527  break;
1528  default:
1529  L_WARNING("invalid sort type\n", procName);
1530  }
1531  }
1532 
1533  /* Get the sort index for data array */
1534  naindex = numaGetBinSortIndex(na, sortorder);
1535  numaDestroy(&na);
1536  if (!naindex)
1537  return (PIXA *)ERROR_PTR("naindex not made", procName, NULL);
1538 
1539  /* Build up sorted pixa using sort index */
1540  if ((pixad = pixaSortByIndex(pixas, naindex, copyflag)) == NULL) {
1541  numaDestroy(&naindex);
1542  return (PIXA *)ERROR_PTR("pixad not made", procName, NULL);
1543  }
1544 
1545  if (pnaindex)
1546  *pnaindex = naindex;
1547  else
1548  numaDestroy(&naindex);
1549  return pixad;
1550 }
1551 
1552 
1561 PIXA *
1563  NUMA *naindex,
1564  l_int32 copyflag)
1565 {
1566 l_int32 i, n, index;
1567 BOX *box;
1568 PIX *pix;
1569 PIXA *pixad;
1570 
1571  PROCNAME("pixaSortByIndex");
1572 
1573  if (!pixas)
1574  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1575  if (!naindex)
1576  return (PIXA *)ERROR_PTR("naindex not defined", procName, NULL);
1577  if (copyflag != L_CLONE && copyflag != L_COPY)
1578  return (PIXA *)ERROR_PTR("invalid copyflag", procName, NULL);
1579 
1580  n = pixaGetCount(pixas);
1581  pixad = pixaCreate(n);
1582  for (i = 0; i < n; i++) {
1583  numaGetIValue(naindex, i, &index);
1584  pix = pixaGetPix(pixas, index, copyflag);
1585  box = pixaGetBox(pixas, index, copyflag);
1586  pixaAddPix(pixad, pix, L_INSERT);
1587  pixaAddBox(pixad, box, L_INSERT);
1588  }
1589 
1590  return pixad;
1591 }
1592 
1593 
1602 PIXAA *
1604  NUMAA *naa,
1605  l_int32 copyflag)
1606 {
1607 l_int32 pixtot, ntot, i, j, n, nn, index;
1608 BOX *box;
1609 NUMA *na;
1610 PIX *pix;
1611 PIXA *pixa;
1612 PIXAA *paa;
1613 
1614  PROCNAME("pixaSort2dByIndex");
1615 
1616  if (!pixas)
1617  return (PIXAA *)ERROR_PTR("pixas not defined", procName, NULL);
1618  if (!naa)
1619  return (PIXAA *)ERROR_PTR("naindex not defined", procName, NULL);
1620 
1621  /* Check counts */
1622  ntot = numaaGetNumberCount(naa);
1623  pixtot = pixaGetCount(pixas);
1624  if (ntot != pixtot)
1625  return (PIXAA *)ERROR_PTR("element count mismatch", procName, NULL);
1626 
1627  n = numaaGetCount(naa);
1628  paa = pixaaCreate(n);
1629  for (i = 0; i < n; i++) {
1630  na = numaaGetNuma(naa, i, L_CLONE);
1631  nn = numaGetCount(na);
1632  pixa = pixaCreate(nn);
1633  for (j = 0; j < nn; j++) {
1634  numaGetIValue(na, j, &index);
1635  pix = pixaGetPix(pixas, index, copyflag);
1636  box = pixaGetBox(pixas, index, copyflag);
1637  pixaAddPix(pixa, pix, L_INSERT);
1638  pixaAddBox(pixa, box, L_INSERT);
1639  }
1640  pixaaAddPixa(paa, pixa, L_INSERT);
1641  numaDestroy(&na);
1642  }
1643 
1644  return paa;
1645 }
1646 
1647 
1648 /*---------------------------------------------------------------------*
1649  * Pixa and Pixaa range selection *
1650  *---------------------------------------------------------------------*/
1667 PIXA *
1669  l_int32 first,
1670  l_int32 last,
1671  l_int32 copyflag)
1672 {
1673 l_int32 n, npix, i;
1674 PIX *pix;
1675 PIXA *pixad;
1676 
1677  PROCNAME("pixaSelectRange");
1678 
1679  if (!pixas)
1680  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1681  if (copyflag != L_COPY && copyflag != L_CLONE)
1682  return (PIXA *)ERROR_PTR("invalid copyflag", procName, NULL);
1683  n = pixaGetCount(pixas);
1684  first = L_MAX(0, first);
1685  if (last < 0) last = n - 1;
1686  if (first >= n)
1687  return (PIXA *)ERROR_PTR("invalid first", procName, NULL);
1688  if (last >= n) {
1689  L_WARNING("last = %d is beyond max index = %d; adjusting\n",
1690  procName, last, n - 1);
1691  last = n - 1;
1692  }
1693  if (first > last)
1694  return (PIXA *)ERROR_PTR("first > last", procName, NULL);
1695 
1696  npix = last - first + 1;
1697  pixad = pixaCreate(npix);
1698  for (i = first; i <= last; i++) {
1699  pix = pixaGetPix(pixas, i, copyflag);
1700  pixaAddPix(pixad, pix, L_INSERT);
1701  }
1702  return pixad;
1703 }
1704 
1705 
1722 PIXAA *
1724  l_int32 first,
1725  l_int32 last,
1726  l_int32 copyflag)
1727 {
1728 l_int32 n, npixa, i;
1729 PIXA *pixa;
1730 PIXAA *paad;
1731 
1732  PROCNAME("pixaaSelectRange");
1733 
1734  if (!paas)
1735  return (PIXAA *)ERROR_PTR("paas not defined", procName, NULL);
1736  if (copyflag != L_COPY && copyflag != L_CLONE)
1737  return (PIXAA *)ERROR_PTR("invalid copyflag", procName, NULL);
1738  n = pixaaGetCount(paas, NULL);
1739  first = L_MAX(0, first);
1740  if (last < 0) last = n - 1;
1741  if (first >= n)
1742  return (PIXAA *)ERROR_PTR("invalid first", procName, NULL);
1743  if (last >= n) {
1744  L_WARNING("last = %d is beyond max index = %d; adjusting\n",
1745  procName, last, n - 1);
1746  last = n - 1;
1747  }
1748  if (first > last)
1749  return (PIXAA *)ERROR_PTR("first > last", procName, NULL);
1750 
1751  npixa = last - first + 1;
1752  paad = pixaaCreate(npixa);
1753  for (i = first; i <= last; i++) {
1754  pixa = pixaaGetPixa(paas, i, copyflag);
1755  pixaaAddPixa(paad, pixa, L_INSERT);
1756  }
1757  return paad;
1758 }
1759 
1760 
1761 /*---------------------------------------------------------------------*
1762  * Pixa and Pixaa scaling *
1763  *---------------------------------------------------------------------*/
1783 PIXAA *
1785  l_int32 wd,
1786  l_int32 hd)
1787 {
1788 l_int32 n, i;
1789 PIXA *pixa1, *pixa2;
1790 PIXAA *paad;
1791 
1792  PROCNAME("pixaaScaleToSize");
1793 
1794  if (!paas)
1795  return (PIXAA *)ERROR_PTR("paas not defined", procName, NULL);
1796  if (wd <= 0 && hd <= 0)
1797  return (PIXAA *)ERROR_PTR("neither wd nor hd > 0", procName, NULL);
1798 
1799  n = pixaaGetCount(paas, NULL);
1800  paad = pixaaCreate(n);
1801  for (i = 0; i < n; i++) {
1802  pixa1 = pixaaGetPixa(paas, i, L_CLONE);
1803  pixa2 = pixaScaleToSize(pixa1, wd, hd);
1804  pixaaAddPixa(paad, pixa2, L_INSERT);
1805  pixaDestroy(&pixa1);
1806  }
1807  return paad;
1808 }
1809 
1810 
1832 PIXAA *
1834  NUMA *nawd,
1835  NUMA *nahd)
1836 {
1837 l_int32 n, i, wd, hd;
1838 PIXA *pixa1, *pixa2;
1839 PIXAA *paad;
1840 
1841  PROCNAME("pixaaScaleToSizeVar");
1842 
1843  if (!paas)
1844  return (PIXAA *)ERROR_PTR("paas not defined", procName, NULL);
1845  if (!nawd && !nahd)
1846  return (PIXAA *)ERROR_PTR("!nawd && !nahd", procName, NULL);
1847 
1848  n = pixaaGetCount(paas, NULL);
1849  if (nawd && (n != numaGetCount(nawd)))
1850  return (PIXAA *)ERROR_PTR("nawd wrong size", procName, NULL);
1851  if (nahd && (n != numaGetCount(nahd)))
1852  return (PIXAA *)ERROR_PTR("nahd wrong size", procName, NULL);
1853  paad = pixaaCreate(n);
1854  for (i = 0; i < n; i++) {
1855  wd = hd = 0;
1856  if (nawd) numaGetIValue(nawd, i, &wd);
1857  if (nahd) numaGetIValue(nahd, i, &hd);
1858  pixa1 = pixaaGetPixa(paas, i, L_CLONE);
1859  pixa2 = pixaScaleToSize(pixa1, wd, hd);
1860  pixaaAddPixa(paad, pixa2, L_INSERT);
1861  pixaDestroy(&pixa1);
1862  }
1863  return paad;
1864 }
1865 
1866 
1880 PIXA *
1882  l_int32 wd,
1883  l_int32 hd)
1884 {
1885 l_int32 n, i;
1886 PIX *pix1, *pix2;
1887 PIXA *pixad;
1888 
1889  PROCNAME("pixaScaleToSize");
1890 
1891  if (!pixas)
1892  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1893 
1894  if (wd <= 0 && hd <= 0) /* no scaling requested */
1895  return pixaCopy(pixas, L_CLONE);
1896 
1897  n = pixaGetCount(pixas);
1898  pixad = pixaCreate(n);
1899  for (i = 0; i < n; i++) {
1900  pix1 = pixaGetPix(pixas, i, L_CLONE);
1901  pix2 = pixScaleToSize(pix1, wd, hd);
1902  pixCopyText(pix2, pix1);
1903  pixaAddPix(pixad, pix2, L_INSERT);
1904  pixDestroy(&pix1);
1905  }
1906  return pixad;
1907 }
1908 
1909 
1925 PIXA *
1927  l_int32 delw,
1928  l_int32 delh)
1929 {
1930 l_int32 n, i;
1931 PIX *pix1, *pix2;
1932 PIXA *pixad;
1933 
1934  PROCNAME("pixaScaleToSizeRel");
1935 
1936  if (!pixas)
1937  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1938 
1939  n = pixaGetCount(pixas);
1940  pixad = pixaCreate(n);
1941  for (i = 0; i < n; i++) {
1942  pix1 = pixaGetPix(pixas, i, L_CLONE);
1943  pix2 = pixScaleToSizeRel(pix1, delw, delh);
1944  if (pix2) {
1945  pixaAddPix(pixad, pix2, L_INSERT);
1946  } else {
1947  L_WARNING("relative scale to size failed; use a copy\n", procName);
1948  pixaAddPix(pixad, pix1, L_COPY);
1949  }
1950  pixDestroy(&pix1);
1951  }
1952  return pixad;
1953 }
1954 
1955 
1969 PIXA *
1971  l_float32 scalex,
1972  l_float32 scaley)
1973 {
1974 l_int32 i, n, nb;
1975 BOXA *boxa1, *boxa2;
1976 PIX *pix1, *pix2;
1977 PIXA *pixad;
1978 
1979  PROCNAME("pixaScale");
1980 
1981  if (!pixas)
1982  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1983  if (scalex <= 0.0 || scaley <= 0.0)
1984  return (PIXA *)ERROR_PTR("invalid scaling parameters", procName, NULL);
1985 
1986  n = pixaGetCount(pixas);
1987  pixad = pixaCreate(n);
1988  for (i = 0; i < n; i++) {
1989  pix1 = pixaGetPix(pixas, i, L_CLONE);
1990  pix2 = pixScale(pix1, scalex, scaley);
1991  pixCopyText(pix2, pix1);
1992  pixaAddPix(pixad, pix2, L_INSERT);
1993  pixDestroy(&pix1);
1994  }
1995 
1996  boxa1 = pixaGetBoxa(pixas, L_CLONE);
1997  nb = boxaGetCount(boxa1);
1998  if (nb == n) {
1999  boxa2 = boxaTransform(boxa1, 0, 0, scalex, scaley);
2000  pixaSetBoxa(pixad, boxa2, L_INSERT);
2001  }
2002  boxaDestroy(&boxa1);
2003  return pixad;
2004 }
2005 
2006 
2020 PIXA *
2022  l_float32 scalex,
2023  l_float32 scaley)
2024 {
2025 l_int32 i, n, nb;
2026 BOXA *boxa1, *boxa2;
2027 PIX *pix1, *pix2;
2028 PIXA *pixad;
2029 
2030  PROCNAME("pixaScaleBySampling");
2031 
2032  if (!pixas)
2033  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
2034  if (scalex <= 0.0 || scaley <= 0.0)
2035  return (PIXA *)ERROR_PTR("invalid scaling parameters", procName, NULL);
2036 
2037  n = pixaGetCount(pixas);
2038  pixad = pixaCreate(n);
2039  for (i = 0; i < n; i++) {
2040  pix1 = pixaGetPix(pixas, i, L_CLONE);
2041  pix2 = pixScaleBySampling(pix1, scalex, scaley);
2042  pixCopyText(pix2, pix1);
2043  pixaAddPix(pixad, pix2, L_INSERT);
2044  pixDestroy(&pix1);
2045  }
2046 
2047  boxa1 = pixaGetBoxa(pixas, L_CLONE);
2048  nb = boxaGetCount(boxa1);
2049  if (nb == n) {
2050  boxa2 = boxaTransform(boxa1, 0, 0, scalex, scaley);
2051  pixaSetBoxa(pixad, boxa2, L_INSERT);
2052  }
2053  boxaDestroy(&boxa1);
2054  return pixad;
2055 }
2056 
2057 
2058 /*---------------------------------------------------------------------*
2059  * Pixa rotation and translation *
2060  *---------------------------------------------------------------------*/
2085 PIXA *
2087  l_float32 angle,
2088  l_int32 type,
2089  l_int32 incolor,
2090  l_int32 width,
2091  l_int32 height)
2092 {
2093 l_int32 i, n;
2094 BOXA *boxa;
2095 PIX *pixs, *pixd;
2096 PIXA *pixad;
2097 
2098  PROCNAME("pixaRotate");
2099 
2100  if (!pixas)
2101  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
2102  if (type != L_ROTATE_SHEAR && type != L_ROTATE_AREA_MAP &&
2103  type != L_ROTATE_SAMPLING)
2104  return (PIXA *)ERROR_PTR("invalid type", procName, NULL);
2105  if (incolor != L_BRING_IN_WHITE && incolor != L_BRING_IN_BLACK)
2106  return (PIXA *)ERROR_PTR("invalid incolor", procName, NULL);
2107  if (L_ABS(angle) < MIN_ANGLE_TO_ROTATE)
2108  return pixaCopy(pixas, L_COPY);
2109 
2110  n = pixaGetCount(pixas);
2111  if ((pixad = pixaCreate(n)) == NULL)
2112  return (PIXA *)ERROR_PTR("pixad not made", procName, NULL);
2113  boxa = pixaGetBoxa(pixad, L_COPY);
2114  pixaSetBoxa(pixad, boxa, L_INSERT);
2115  for (i = 0; i < n; i++) {
2116  if ((pixs = pixaGetPix(pixas, i, L_CLONE)) == NULL) {
2117  pixaDestroy(&pixad);
2118  return (PIXA *)ERROR_PTR("pixs not found", procName, NULL);
2119  }
2120  pixd = pixRotate(pixs, angle, type, incolor, width, height);
2121  pixaAddPix(pixad, pixd, L_INSERT);
2122  pixDestroy(&pixs);
2123  }
2124 
2125  return pixad;
2126 }
2127 
2128 
2143 PIXA *
2145  l_int32 rotation)
2146 {
2147 l_int32 i, n, nb, w, h;
2148 BOX *boxs, *boxd;
2149 PIX *pixs, *pixd;
2150 PIXA *pixad;
2151 
2152  PROCNAME("pixaRotateOrth");
2153 
2154  if (!pixas)
2155  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
2156  if (rotation < 0 || rotation > 3)
2157  return (PIXA *)ERROR_PTR("rotation not in {0,1,2,3}", procName, NULL);
2158  if (rotation == 0)
2159  return pixaCopy(pixas, L_COPY);
2160 
2161  n = pixaGetCount(pixas);
2162  nb = pixaGetBoxaCount(pixas);
2163  if ((pixad = pixaCreate(n)) == NULL)
2164  return (PIXA *)ERROR_PTR("pixad not made", procName, NULL);
2165  for (i = 0; i < n; i++) {
2166  if ((pixs = pixaGetPix(pixas, i, L_CLONE)) == NULL) {
2167  pixaDestroy(&pixad);
2168  return (PIXA *)ERROR_PTR("pixs not found", procName, NULL);
2169  }
2170  pixd = pixRotateOrth(pixs, rotation);
2171  pixaAddPix(pixad, pixd, L_INSERT);
2172  if (n == nb) {
2173  boxs = pixaGetBox(pixas, i, L_COPY);
2174  pixGetDimensions(pixs, &w, &h, NULL);
2175  boxd = boxRotateOrth(boxs, w, h, rotation);
2176  pixaAddBox(pixad, boxd, L_INSERT);
2177  boxDestroy(&boxs);
2178  }
2179  pixDestroy(&pixs);
2180  }
2181 
2182  return pixad;
2183 }
2184 
2185 
2195 PIXA *
2197  l_int32 hshift,
2198  l_int32 vshift,
2199  l_int32 incolor)
2200 {
2201 l_int32 i, n, nb;
2202 BOXA *boxas, *boxad;
2203 PIX *pixs, *pixd;
2204 PIXA *pixad;
2205 
2206  PROCNAME("pixaTranslate");
2207 
2208  if (!pixas)
2209  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
2210  if (hshift == 0 && vshift == 0)
2211  return pixaCopy(pixas, L_COPY);
2212 
2213  n = pixaGetCount(pixas);
2214  nb = pixaGetBoxaCount(pixas);
2215  if ((pixad = pixaCreate(n)) == NULL)
2216  return (PIXA *)ERROR_PTR("pixad not made", procName, NULL);
2217  for (i = 0; i < n; i++) {
2218  if ((pixs = pixaGetPix(pixas, i, L_CLONE)) == NULL) {
2219  pixaDestroy(&pixad);
2220  return (PIXA *)ERROR_PTR("pixs not found", procName, NULL);
2221  }
2222  pixd = pixTranslate(NULL, pixs, hshift, vshift, incolor);
2223  pixaAddPix(pixad, pixd, L_INSERT);
2224  pixDestroy(&pixs);
2225  }
2226  if (n == nb) {
2227  boxas = pixaGetBoxa(pixas, L_CLONE);
2228  boxad = boxaTransform(boxas, hshift, vshift, 1.0, 1.0);
2229  pixaSetBoxa(pixad, boxad, L_INSERT);
2230  boxaDestroy(&boxas);
2231  }
2232 
2233  return pixad;
2234 }
2235 
2236 
2237 /*---------------------------------------------------------------------*
2238  * Miscellaneous functions *
2239  *---------------------------------------------------------------------*/
2269 PIXA *
2271  PIXA *pixas,
2272  l_int32 left,
2273  l_int32 right,
2274  l_int32 top,
2275  l_int32 bot,
2276  l_uint32 val)
2277 {
2278 l_int32 i, n, nbox;
2279 BOX *box;
2280 BOXA *boxad;
2281 PIX *pixs, *pixd;
2282 
2283  PROCNAME("pixaAddBorderGeneral");
2284 
2285  if (!pixas)
2286  return (PIXA *)ERROR_PTR("pixas not defined", procName, pixad);
2287  if (left < 0 || right < 0 || top < 0 || bot < 0)
2288  return (PIXA *)ERROR_PTR("negative border added!", procName, pixad);
2289  if (pixad && (pixad != pixas))
2290  return (PIXA *)ERROR_PTR("pixad defined but != pixas", procName, pixad);
2291 
2292  n = pixaGetCount(pixas);
2293  if (!pixad)
2294  pixad = pixaCreate(n);
2295  for (i = 0; i < n; i++) {
2296  pixs = pixaGetPix(pixas, i, L_CLONE);
2297  pixd = pixAddBorderGeneral(pixs, left, right, top, bot, val);
2298  if (pixad == pixas) /* replace */
2299  pixaReplacePix(pixad, i, pixd, NULL);
2300  else
2301  pixaAddPix(pixad, pixd, L_INSERT);
2302  pixDestroy(&pixs);
2303  }
2304 
2305  nbox = pixaGetBoxaCount(pixas);
2306  boxad = pixaGetBoxa(pixad, L_CLONE);
2307  for (i = 0; i < nbox; i++) {
2308  if ((box = pixaGetBox(pixas, i, L_COPY)) == NULL) {
2309  L_WARNING("box %d not found\n", procName, i);
2310  break;
2311  }
2312  boxAdjustSides(box, box, -left, right, -top, bot);
2313  if (pixad == pixas) /* replace */
2314  boxaReplaceBox(boxad, i, box);
2315  else
2316  boxaAddBox(boxad, box, L_INSERT);
2317  }
2318  boxaDestroy(&boxad);
2319 
2320  return pixad;
2321 }
2322 
2323 
2340 PIXA *
2342  NUMA **pnaindex,
2343  l_int32 copyflag)
2344 {
2345 l_int32 i, j, m, mb, n;
2346 BOX *box;
2347 NUMA *naindex;
2348 PIX *pix;
2349 PIXA *pixa, *pixat;
2350 
2351  PROCNAME("pixaaFlattenToPixa");
2352 
2353  if (pnaindex) *pnaindex = NULL;
2354  if (!paa)
2355  return (PIXA *)ERROR_PTR("paa not defined", procName, NULL);
2356  if (copyflag != L_COPY && copyflag != L_CLONE)
2357  return (PIXA *)ERROR_PTR("invalid copyflag", procName, NULL);
2358 
2359  if (pnaindex) {
2360  naindex = numaCreate(0);
2361  *pnaindex = naindex;
2362  }
2363 
2364  n = pixaaGetCount(paa, NULL);
2365  pixa = pixaCreate(n);
2366  for (i = 0; i < n; i++) {
2367  pixat = pixaaGetPixa(paa, i, L_CLONE);
2368  m = pixaGetCount(pixat);
2369  mb = pixaGetBoxaCount(pixat);
2370  for (j = 0; j < m; j++) {
2371  pix = pixaGetPix(pixat, j, copyflag);
2372  pixaAddPix(pixa, pix, L_INSERT);
2373  if (j < mb) {
2374  box = pixaGetBox(pixat, j, copyflag);
2375  pixaAddBox(pixa, box, L_INSERT);
2376  }
2377  if (pnaindex)
2378  numaAddNumber(naindex, i); /* save 'row' number */
2379  }
2380  pixaDestroy(&pixat);
2381  }
2382 
2383  return pixa;
2384 }
2385 
2386 
2395 l_ok
2397  l_int32 *pminw,
2398  l_int32 *pminh,
2399  l_int32 *pmaxw,
2400  l_int32 *pmaxh)
2401 {
2402 l_int32 minw, minh, maxw, maxh, minpw, minph, maxpw, maxph, i, n;
2403 PIXA *pixa;
2404 
2405  PROCNAME("pixaaSizeRange");
2406 
2407  if (pminw) *pminw = 0;
2408  if (pminh) *pminh = 0;
2409  if (pmaxw) *pmaxw = 0;
2410  if (pmaxh) *pmaxh = 0;
2411  if (!paa)
2412  return ERROR_INT("paa not defined", procName, 1);
2413  if (!pminw && !pmaxw && !pminh && !pmaxh)
2414  return ERROR_INT("no data can be returned", procName, 1);
2415 
2416  minw = minh = 100000000;
2417  maxw = maxh = 0;
2418  n = pixaaGetCount(paa, NULL);
2419  for (i = 0; i < n; i++) {
2420  pixa = pixaaGetPixa(paa, i, L_CLONE);
2421  pixaSizeRange(pixa, &minpw, &minph, &maxpw, &maxph);
2422  if (minpw < minw)
2423  minw = minpw;
2424  if (minph < minh)
2425  minh = minph;
2426  if (maxpw > maxw)
2427  maxw = maxpw;
2428  if (maxph > maxh)
2429  maxh = maxph;
2430  pixaDestroy(&pixa);
2431  }
2432 
2433  if (pminw) *pminw = minw;
2434  if (pminh) *pminh = minh;
2435  if (pmaxw) *pmaxw = maxw;
2436  if (pmaxh) *pmaxh = maxh;
2437  return 0;
2438 }
2439 
2440 
2449 l_ok
2451  l_int32 *pminw,
2452  l_int32 *pminh,
2453  l_int32 *pmaxw,
2454  l_int32 *pmaxh)
2455 {
2456 l_int32 minw, minh, maxw, maxh, i, n, w, h;
2457 PIX *pix;
2458 
2459  PROCNAME("pixaSizeRange");
2460 
2461  if (pminw) *pminw = 0;
2462  if (pminh) *pminh = 0;
2463  if (pmaxw) *pmaxw = 0;
2464  if (pmaxh) *pmaxh = 0;
2465  if (!pixa)
2466  return ERROR_INT("pixa not defined", procName, 1);
2467  if (!pminw && !pmaxw && !pminh && !pmaxh)
2468  return ERROR_INT("no data can be returned", procName, 1);
2469 
2470  minw = minh = 1000000;
2471  maxw = maxh = 0;
2472  n = pixaGetCount(pixa);
2473  for (i = 0; i < n; i++) {
2474  pix = pixaGetPix(pixa, i, L_CLONE);
2475  w = pixGetWidth(pix);
2476  h = pixGetHeight(pix);
2477  if (w < minw)
2478  minw = w;
2479  if (h < minh)
2480  minh = h;
2481  if (w > maxw)
2482  maxw = w;
2483  if (h > maxh)
2484  maxh = h;
2485  pixDestroy(&pix);
2486  }
2487 
2488  if (pminw) *pminw = minw;
2489  if (pminh) *pminh = minh;
2490  if (pmaxw) *pmaxw = maxw;
2491  if (pmaxh) *pmaxh = maxh;
2492 
2493  return 0;
2494 }
2495 
2496 
2519 PIXA *
2521  PIX *pixs)
2522 {
2523 l_int32 i, n;
2524 BOX *box;
2525 PIX *pix, *pixc;
2526 PIXA *pixad;
2527 
2528  PROCNAME("pixaClipToPix");
2529 
2530  if (!pixas)
2531  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
2532  if (!pixs)
2533  return (PIXA *)ERROR_PTR("pixs not defined", procName, NULL);
2534 
2535  n = pixaGetCount(pixas);
2536  if ((pixad = pixaCreate(n)) == NULL)
2537  return (PIXA *)ERROR_PTR("pixad not made", procName, NULL);
2538 
2539  for (i = 0; i < n; i++) {
2540  pix = pixaGetPix(pixas, i, L_CLONE);
2541  box = pixaGetBox(pixas, i, L_COPY);
2542  pixc = pixClipRectangle(pixs, box, NULL);
2543  pixAnd(pixc, pixc, pix);
2544  pixaAddPix(pixad, pixc, L_INSERT);
2545  pixaAddBox(pixad, box, L_INSERT);
2546  pixDestroy(&pix);
2547  }
2548 
2549  return pixad;
2550 }
2551 
2552 
2568 l_ok
2570  PIXA **ppixad,
2571  BOXA **pboxa)
2572 {
2573 l_int32 i, n;
2574 BOX *box1;
2575 PIX *pix1, *pix2;
2576 
2577  PROCNAME("pixaClipToForeground");
2578 
2579  if (ppixad) *ppixad = NULL;
2580  if (pboxa) *pboxa = NULL;
2581  if (!pixas)
2582  return ERROR_INT("pixas not defined", procName, 1);
2583  if (!ppixad && !pboxa)
2584  return ERROR_INT("no output requested", procName, 1);
2585 
2586  n = pixaGetCount(pixas);
2587  if (ppixad) *ppixad = pixaCreate(n);
2588  if (pboxa) *pboxa = boxaCreate(n);
2589  for (i = 0; i < n; i++) {
2590  pix1 = pixaGetPix(pixas, i, L_CLONE);
2591  pixClipToForeground(pix1, &pix2, &box1);
2592  pixDestroy(&pix1);
2593  if (ppixad)
2594  pixaAddPix(*ppixad, pix2, L_INSERT);
2595  else
2596  pixDestroy(&pix2);
2597  if (pboxa)
2598  boxaAddBox(*pboxa, box1, L_INSERT);
2599  else
2600  boxDestroy(&box1);
2601  }
2602 
2603  return 0;
2604 }
2605 
2606 
2614 l_ok
2616  l_int32 *pdepth)
2617 {
2618 l_int32 hascolor, maxdepth;
2619 
2620  PROCNAME("pixaGetRenderingDepth");
2621 
2622  if (!pdepth)
2623  return ERROR_INT("&depth not defined", procName, 1);
2624  *pdepth = 0;
2625  if (!pixa)
2626  return ERROR_INT("pixa not defined", procName, 1);
2627 
2628  pixaHasColor(pixa, &hascolor);
2629  if (hascolor) {
2630  *pdepth = 32;
2631  return 0;
2632  }
2633 
2634  pixaGetDepthInfo(pixa, &maxdepth, NULL);
2635  if (maxdepth == 1)
2636  *pdepth = 1;
2637  else /* 2, 4, 8 or 16 */
2638  *pdepth = 8;
2639  return 0;
2640 }
2641 
2642 
2651 l_ok
2653  l_int32 *phascolor)
2654 {
2655 l_int32 i, n, hascolor, d;
2656 PIX *pix;
2657 PIXCMAP *cmap;
2658 
2659  PROCNAME("pixaHasColor");
2660 
2661  if (!phascolor)
2662  return ERROR_INT("&hascolor not defined", procName, 1);
2663  *phascolor = 0;
2664  if (!pixa)
2665  return ERROR_INT("pixa not defined", procName, 1);
2666 
2667  n = pixaGetCount(pixa);
2668  hascolor = 0;
2669  for (i = 0; i < n; i++) {
2670  pix = pixaGetPix(pixa, i, L_CLONE);
2671  if ((cmap = pixGetColormap(pix)) != NULL)
2672  pixcmapHasColor(cmap, &hascolor);
2673  d = pixGetDepth(pix);
2674  pixDestroy(&pix);
2675  if (d == 32 || hascolor == 1) {
2676  *phascolor = 1;
2677  break;
2678  }
2679  }
2680 
2681  return 0;
2682 }
2683 
2684 
2692 l_ok
2694  l_int32 *phascmap)
2695 {
2696 l_int32 i, n;
2697 PIX *pix;
2698 PIXCMAP *cmap;
2699 
2700  PROCNAME("pixaAnyColormaps");
2701 
2702  if (!phascmap)
2703  return ERROR_INT("&hascmap not defined", procName, 1);
2704  *phascmap = 0;
2705  if (!pixa)
2706  return ERROR_INT("pixa not defined", procName, 1);
2707 
2708  n = pixaGetCount(pixa);
2709  for (i = 0; i < n; i++) {
2710  pix = pixaGetPix(pixa, i, L_CLONE);
2711  cmap = pixGetColormap(pix);
2712  pixDestroy(&pix);
2713  if (cmap) {
2714  *phascmap = 1;
2715  return 0;
2716  }
2717  }
2718 
2719  return 0;
2720 }
2721 
2722 
2731 l_ok
2733  l_int32 *pmaxdepth,
2734  l_int32 *psame)
2735 {
2736 l_int32 i, n, d, d0;
2737 l_int32 maxd, same; /* depth info */
2738 
2739  PROCNAME("pixaGetDepthInfo");
2740 
2741  if (pmaxdepth) *pmaxdepth = 0;
2742  if (psame) *psame = TRUE;
2743  if (!pmaxdepth && !psame) return 0;
2744  if (!pixa)
2745  return ERROR_INT("pixa not defined", procName, 1);
2746  if ((n = pixaGetCount(pixa)) == 0)
2747  return ERROR_INT("pixa is empty", procName, 1);
2748 
2749  same = TRUE;
2750  maxd = 0;
2751  for (i = 0; i < n; i++) {
2752  pixaGetPixDimensions(pixa, i, NULL, NULL, &d);
2753  if (i == 0)
2754  d0 = d;
2755  else if (d != d0)
2756  same = FALSE;
2757  if (d > maxd) maxd = d;
2758  }
2759 
2760  if (pmaxdepth) *pmaxdepth = maxd;
2761  if (psame) *psame = same;
2762  return 0;
2763 }
2764 
2765 
2780 PIXA *
2782 {
2783 l_int32 i, n, same, hascmap, maxdepth;
2784 BOXA *boxa;
2785 PIX *pix1, *pix2;
2786 PIXA *pixa1, *pixad;
2787 
2788  PROCNAME("pixaConvertToSameDepth");
2789 
2790  if (!pixas)
2791  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
2792 
2793  /* Remove colormaps to rgb */
2794  if ((n = pixaGetCount(pixas)) == 0)
2795  return (PIXA *)ERROR_PTR("no components", procName, NULL);
2796  pixaAnyColormaps(pixas, &hascmap);
2797  if (hascmap) {
2798  pixa1 = pixaCreate(n);
2799  for (i = 0; i < n; i++) {
2800  pix1 = pixaGetPix(pixas, i, L_CLONE);
2801  pix2 = pixConvertTo32(pix1);
2802  pixaAddPix(pixa1, pix2, L_INSERT);
2803  pixDestroy(&pix1);
2804  }
2805  } else {
2806  pixa1 = pixaCopy(pixas, L_CLONE);
2807  }
2808 
2809  pixaGetDepthInfo(pixa1, &maxdepth, &same);
2810  if (!same) { /* at least one pix has depth < maxdepth */
2811  pixad = pixaCreate(n);
2812  for (i = 0; i < n; i++) {
2813  pix1 = pixaGetPix(pixa1, i, L_CLONE);
2814  if (maxdepth <= 8)
2815  pix2 = pixConvertTo8(pix1, 0);
2816  else
2817  pix2 = pixConvertTo32(pix1);
2818  pixaAddPix(pixad, pix2, L_INSERT);
2819  pixDestroy(&pix1);
2820  }
2821  } else {
2822  pixad = pixaCopy(pixa1, L_CLONE);
2823  }
2824 
2825  boxa = pixaGetBoxa(pixas, L_COPY);
2826  pixaSetBoxa(pixad, boxa, L_INSERT);
2827  pixaDestroy(&pixa1);
2828  return pixad;
2829 }
2830 
2831 
2860 l_ok
2862  PIXA *pixa2,
2863  l_int32 maxdist,
2864  NUMA **pnaindex,
2865  l_int32 *psame)
2866 {
2867 l_int32 i, j, n, empty1, empty2, same, sameboxa;
2868 BOXA *boxa1, *boxa2;
2869 NUMA *na;
2870 PIX *pix1, *pix2;
2871 
2872  PROCNAME("pixaEqual");
2873 
2874  if (pnaindex) *pnaindex = NULL;
2875  if (!psame)
2876  return ERROR_INT("&same not defined", procName, 1);
2877  *psame = 0;
2878  sameboxa = 0;
2879  na = NULL;
2880  if (!pixa1 || !pixa2)
2881  return ERROR_INT("pixa1 and pixa2 not both defined", procName, 1);
2882  n = pixaGetCount(pixa1);
2883  if (n != pixaGetCount(pixa2))
2884  return 0;
2885 
2886  /* If there are no boxes, strict ordering of the pix in each
2887  * pixa is required. */
2888  boxa1 = pixaGetBoxa(pixa1, L_CLONE);
2889  boxa2 = pixaGetBoxa(pixa2, L_CLONE);
2890  empty1 = (boxaGetCount(boxa1) == 0) ? 1 : 0;
2891  empty2 = (boxaGetCount(boxa2) == 0) ? 1 : 0;
2892  if (!empty1 && !empty2) {
2893  boxaEqual(boxa1, boxa2, maxdist, &na, &sameboxa);
2894  if (!sameboxa) {
2895  boxaDestroy(&boxa1);
2896  boxaDestroy(&boxa2);
2897  numaDestroy(&na);
2898  return 0;
2899  }
2900  }
2901  boxaDestroy(&boxa1);
2902  boxaDestroy(&boxa2);
2903  if ((!empty1 && empty2) || (empty1 && !empty2))
2904  return 0;
2905 
2906  for (i = 0; i < n; i++) {
2907  pix1 = pixaGetPix(pixa1, i, L_CLONE);
2908  if (na)
2909  numaGetIValue(na, i, &j);
2910  else
2911  j = i;
2912  pix2 = pixaGetPix(pixa2, j, L_CLONE);
2913  pixEqual(pix1, pix2, &same);
2914  pixDestroy(&pix1);
2915  pixDestroy(&pix2);
2916  if (!same) {
2917  numaDestroy(&na);
2918  return 0;
2919  }
2920  }
2921 
2922  *psame = 1;
2923  if (pnaindex)
2924  *pnaindex = na;
2925  else
2926  numaDestroy(&na);
2927  return 0;
2928 }
2929 
2930 
2944 l_ok
2946 {
2947 l_int32 i, n, w, h;
2948 BOX *box;
2949 BOXA *boxa;
2950 PIX *pix;
2951 
2952  PROCNAME("pixaSetFullSizeBoxa");
2953 
2954  if (!pixa)
2955  return ERROR_INT("pixa not defined", procName, 1);
2956  if ((n = pixaGetCount(pixa)) == 0) {
2957  L_INFO("pixa contains no pix\n", procName);
2958  return 0;
2959  }
2960 
2961  boxa = boxaCreate(n);
2962  pixaSetBoxa(pixa, boxa, L_INSERT);
2963  for (i = 0; i < n; i++) {
2964  pix = pixaGetPix(pixa, i, L_CLONE);
2965  pixGetDimensions(pix, &w, &h, NULL);
2966  box = boxCreate(0, 0, w, h);
2967  boxaAddBox(boxa, box, L_INSERT);
2968  pixDestroy(&pix);
2969  }
2970  return 0;
2971 }
2972 
PIXA * pixaSelectByPerimToAreaRatio(PIXA *pixas, l_float32 thresh, l_int32 type, l_int32 *pchanged)
pixaSelectByPerimToAreaRatio()
Definition: pixafunc1.c:520
PIXA * pixaRotate(PIXA *pixas, l_float32 angle, l_int32 type, l_int32 incolor, l_int32 width, l_int32 height)
pixaRotate()
Definition: pixafunc1.c:2086
l_ok pixaEqual(PIXA *pixa1, PIXA *pixa2, l_int32 maxdist, NUMA **pnaindex, l_int32 *psame)
pixaEqual()
Definition: pixafunc1.c:2861
PIXA * pixaSortByIndex(PIXA *pixas, NUMA *naindex, l_int32 copyflag)
pixaSortByIndex()
Definition: pixafunc1.c:1562
PIXAA * pixaaCreate(l_int32 n)
pixaaCreate()
Definition: pixabasic.c:1825
l_ok pixAddWithIndicator(PIX *pixs, PIXA *pixa, NUMA *na)
pixAddWithIndicator()
Definition: pixafunc1.c:1140
BOX * boxRotateOrth(BOX *box, l_int32 w, l_int32 h, l_int32 rotation)
boxRotateOrth()
Definition: boxfunc2.c:514
l_ok boxaEqual(BOXA *boxa1, BOXA *boxa2, l_int32 maxdist, NUMA **pnaindex, l_int32 *psame)
boxaEqual()
Definition: boxfunc1.c:2143
Definition: pix.h:717
PIXAA * pixaSort2dByIndex(PIXA *pixas, NUMAA *naa, l_int32 copyflag)
pixaSort2dByIndex()
Definition: pixafunc1.c:1603
NUMA * numaGetSortIndex(NUMA *na, l_int32 sortorder)
numaGetSortIndex()
Definition: numafunc1.c:2637
NUMA * pixaFindAreaFraction(PIXA *pixa)
pixaFindAreaFraction()
Definition: pix5.c:435
PIX * pixScaleToSizeRel(PIX *pixs, l_int32 delw, l_int32 delh)
pixScaleToSizeRel()
Definition: scale1.c:274
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3233
l_ok pixaaSizeRange(PIXAA *paa, l_int32 *pminw, l_int32 *pminh, l_int32 *pmaxw, l_int32 *pmaxh)
pixaaSizeRange()
Definition: pixafunc1.c:2396
struct Boxa * boxa
Definition: pix.h:460
PIXA * pixaSelectWithIndicator(PIXA *pixas, NUMA *na, l_int32 *pchanged)
pixaSelectWithIndicator()
Definition: pixafunc1.c:1027
l_ok pixaVerifyDepth(PIXA *pixa, l_int32 *psame, l_int32 *pmaxd)
pixaVerifyDepth()
Definition: pixabasic.c:941
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:473
l_int32 numaaGetNumberCount(NUMAA *naa)
numaaGetNumberCount()
Definition: numabasic.c:1589
PIXA * pixaCreate(l_int32 n)
pixaCreate()
Definition: pixabasic.c:163
NUMA * numaGetBinSortIndex(NUMA *nas, l_int32 sortorder)
numaGetBinSortIndex()
Definition: numafunc1.c:2713
l_ok pixaSetBoxa(PIXA *pixa, BOXA *boxa, l_int32 accesstype)
pixaSetBoxa()
Definition: pixabasic.c:877
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
PIXA * pixaaGetPixa(PIXAA *paa, l_int32 index, l_int32 accesstype)
pixaaGetPixa()
Definition: pixabasic.c:2168
PIX * pixConvertTo8(PIX *pixs, l_int32 cmapflag)
pixConvertTo8()
Definition: pixconv.c:3041
l_int32 pixaaGetCount(PIXAA *paa, NUMA **pna)
pixaaGetCount()
Definition: pixabasic.c:2119
PIXA * pixaRotateOrth(PIXA *pixas, l_int32 rotation)
pixaRotateOrth()
Definition: pixafunc1.c:2144
PIXA * pixaaFlattenToPixa(PIXAA *paa, NUMA **pnaindex, l_int32 copyflag)
pixaaFlattenToPixa()
Definition: pixafunc1.c:2341
l_ok boxaReplaceBox(BOXA *boxa, l_int32 index, BOX *box)
boxaReplaceBox()
Definition: boxbasic.c:946
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:302
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:212
PIXA * pixaConvertToSameDepth(PIXA *pixas)
pixaConvertToSameDepth()
Definition: pixafunc1.c:2781
NUMA * pixaFindWidthHeightRatio(PIXA *pixa)
pixaFindWidthHeightRatio()
Definition: pix5.c:664
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:187
l_ok pixaGetDepthInfo(PIXA *pixa, l_int32 *pmaxdepth, l_int32 *psame)
pixaGetDepthInfo()
Definition: pixafunc1.c:2732
void boxaDestroy(BOXA **pboxa)
boxaDestroy()
Definition: boxbasic.c:580
BOX * pixaGetBox(PIXA *pixa, l_int32 index, l_int32 accesstype)
pixaGetBox()
Definition: pixabasic.c:797
NUMA * pixaFindPerimSizeRatio(PIXA *pixa)
pixaFindPerimSizeRatio()
Definition: pix5.c:339
PIX * pixScaleBySampling(PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScaleBySampling()
Definition: scale1.c:1338
PIX * pixaDisplay(PIXA *pixa, l_int32 w, l_int32 h)
pixaDisplay()
Definition: pixafunc2.c:184
PIXA * pixaScaleToSize(PIXA *pixas, l_int32 wd, l_int32 hd)
pixaScaleToSize()
Definition: pixafunc1.c:1881
PIX * pixCreateTemplate(PIX *pixs)
pixCreateTemplate()
Definition: pix1.c:367
PIX * pixClipRectangle(PIX *pixs, BOX *box, BOX **pboxc)
pixClipRectangle()
Definition: pix5.c:1020
Definition: pix.h:492
NUMA * pixaFindPerimToAreaRatio(PIXA *pixa)
pixaFindPerimToAreaRatio()
Definition: pix5.c:235
l_ok pixaSetFullSizeBoxa(PIXA *pixa)
pixaSetFullSizeBoxa()
Definition: pixafunc1.c:2945
l_int32 pixaGetBoxaCount(PIXA *pixa)
pixaGetBoxaCount()
Definition: pixabasic.c:765
PIX * pixaRenderComponent(PIX *pixs, PIXA *pixa, l_int32 index)
pixaRenderComponent()
Definition: pixafunc1.c:1264
l_ok pixaHasColor(PIXA *pixa, l_int32 *phascolor)
pixaHasColor()
Definition: pixafunc1.c:2652
l_ok pixClipToForeground(PIX *pixs, PIX **ppixd, BOX **pbox)
pixClipToForeground()
Definition: pix5.c:1660
PIXA * pixaCopy(PIXA *pixa, l_int32 copyflag)
pixaCopy()
Definition: pixabasic.c:450
PIXA * pixaSelectByNumConnComp(PIXA *pixas, l_int32 nmin, l_int32 nmax, l_int32 connectivity, l_int32 *pchanged)
pixaSelectByNumConnComp()
Definition: pixafunc1.c:968
PIXAA * pixaaScaleToSize(PIXAA *paas, l_int32 wd, l_int32 hd)
pixaaScaleToSize()
Definition: pixafunc1.c:1784
BOXA * pixConnComp(PIX *pixs, PIXA **ppixa, l_int32 connectivity)
pixConnComp()
Definition: conncomp.c:147
NUMA * numaaGetNuma(NUMAA *naa, l_int32 index, l_int32 accessflag)
numaaGetNuma()
Definition: numabasic.c:1659
l_ok numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition: numabasic.c:727
PIXA * pixaScaleBySampling(PIXA *pixas, l_float32 scalex, l_float32 scaley)
pixaScaleBySampling()
Definition: pixafunc1.c:2021
l_ok pixaAddPix(PIXA *pixa, PIX *pix, l_int32 copyflag)
pixaAddPix()
Definition: pixabasic.c:503
Definition: array.h:59
PIX * pixSelectByAreaFraction(PIX *pixs, l_float32 thresh, l_int32 connectivity, l_int32 type, l_int32 *pchanged)
pixSelectByAreaFraction()
Definition: pixafunc1.c:707
PIXAA * pixaaSelectRange(PIXAA *paas, l_int32 first, l_int32 last, l_int32 copyflag)
pixaaSelectRange()
Definition: pixafunc1.c:1723
PIXA * pixaSelectByWidthHeightRatio(PIXA *pixas, l_float32 thresh, l_int32 type, l_int32 *pchanged)
pixaSelectByWidthHeightRatio()
Definition: pixafunc1.c:918
BOXA * boxaTransform(BOXA *boxas, l_int32 shiftx, l_int32 shifty, l_float32 scalex, l_float32 scaley)
boxaTransform()
Definition: boxfunc2.c:93
l_int32 numaGetCount(NUMA *na)
numaGetCount()
Definition: numabasic.c:631
PIXA * pixaTranslate(PIXA *pixas, l_int32 hshift, l_int32 vshift, l_int32 incolor)
pixaTranslate()
Definition: pixafunc1.c:2196
PIX * pixAnd(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixAnd()
Definition: pix3.c:1510
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
l_ok boxaAddBox(BOXA *boxa, BOX *box, l_int32 copyflag)
boxaAddBox()
Definition: boxbasic.c:618
PIXA * pixaSelectBySize(PIXA *pixas, l_int32 width, l_int32 height, l_int32 type, l_int32 relation, l_int32 *pchanged)
pixaSelectBySize()
Definition: pixafunc1.c:299
PIXA * pixaSelectByPerimSizeRatio(PIXA *pixas, l_float32 thresh, l_int32 type, l_int32 *pchanged)
pixaSelectByPerimSizeRatio()
Definition: pixafunc1.c:651
PIX * pixSelectByPerimToAreaRatio(PIX *pixs, l_float32 thresh, l_int32 connectivity, l_int32 type, l_int32 *pchanged)
pixSelectByPerimToAreaRatio()
Definition: pixafunc1.c:446
PIXAA * pixaaScaleToSizeVar(PIXAA *paas, NUMA *nawd, NUMA *nahd)
pixaaScaleToSizeVar()
Definition: pixafunc1.c:1833
BOX * boxAdjustSides(BOX *boxd, BOX *boxs, l_int32 delleft, l_int32 delright, l_int32 deltop, l_int32 delbot)
boxAdjustSides()
Definition: boxfunc1.c:1807
l_ok pixRemoveWithIndicator(PIX *pixs, PIXA *pixa, NUMA *na)
pixRemoveWithIndicator()
Definition: pixafunc1.c:1087
NUMA * numaMakeThresholdIndicator(NUMA *nas, l_float32 thresh, l_int32 type)
numaMakeThresholdIndicator()
Definition: numafunc1.c:1153
PIX * pixScaleToSize(PIX *pixs, l_int32 wd, l_int32 hd)
pixScaleToSize()
Definition: scale1.c:317
Definition: array.h:71
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:543
l_ok pixCopyColormap(PIX *pixd, PIX *pixs)
pixCopyColormap()
Definition: pix1.c:745
PIX * pixSelectByWidthHeightRatio(PIX *pixs, l_float32 thresh, l_int32 connectivity, l_int32 type, l_int32 *pchanged)
pixSelectByWidthHeightRatio()
Definition: pixafunc1.c:840
PIX * pixRotateOrth(PIX *pixs, l_int32 quads)
pixRotateOrth()
Definition: rotateorth.c:72
BOX * boxaGetBox(BOXA *boxa, l_int32 index, l_int32 accessflag)
boxaGetBox()
Definition: boxbasic.c:763
PIXA * pixaScaleToSizeRel(PIXA *pixas, l_int32 delw, l_int32 delh)
pixaScaleToSizeRel()
Definition: pixafunc1.c:1926
PIXA * pixaSort(PIXA *pixas, l_int32 sorttype, l_int32 sortorder, NUMA **pnaindex, l_int32 copyflag)
pixaSort()
Definition: pixafunc1.c:1334
l_ok pixcmapHasColor(PIXCMAP *cmap, l_int32 *pcolor)
pixcmapHasColor()
Definition: colormap.c:1002
NUMA * numaCreateFromString(const char *str)
numaCreateFromString()
Definition: numabasic.c:309
Definition: pix.h:454
l_ok boxaGetExtent(BOXA *boxa, l_int32 *pw, l_int32 *ph, BOX **pbox)
boxaGetExtent()
Definition: boxfunc4.c:943
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:360
Definition: pix.h:465
PIXA * pixaSelectByAreaFraction(PIXA *pixas, l_float32 thresh, l_int32 type, l_int32 *pchanged)
pixaSelectByAreaFraction()
Definition: pixafunc1.c:785
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1065
l_ok pixaSizeRange(PIXA *pixa, l_int32 *pminw, l_int32 *pminh, l_int32 *pmaxw, l_int32 *pmaxh)
pixaSizeRange()
Definition: pixafunc1.c:2450
NUMA * pixaMakeSizeIndicator(PIXA *pixa, l_int32 width, l_int32 height, l_int32 type, l_int32 relation)
pixaMakeSizeIndicator()
Definition: pixafunc1.c:355
l_ok pixaGetRenderingDepth(PIXA *pixa, l_int32 *pdepth)
pixaGetRenderingDepth()
Definition: pixafunc1.c:2615
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:2270
l_int32 numaaGetCount(NUMAA *naa)
numaaGetCount()
Definition: numabasic.c:1550
PIXA * pixaScale(PIXA *pixas, l_float32 scalex, l_float32 scaley)
pixaScale()
Definition: pixafunc1.c:1970
PIX * pixaGetPix(PIXA *pixa, l_int32 index, l_int32 accesstype)
pixaGetPix()
Definition: pixabasic.c:672
PIX * pixSelectByPerimSizeRatio(PIX *pixs, l_float32 thresh, l_int32 connectivity, l_int32 type, l_int32 *pchanged)
pixSelectByPerimSizeRatio()
Definition: pixafunc1.c:577
Definition: pix.h:718
l_ok pixaaAddPixa(PIXAA *paa, PIXA *pixa, l_int32 copyflag)
pixaaAddPixa()
Definition: pixabasic.c:1976
#define PIX_NOT(op)
Definition: pix.h:329
Definition: pix.h:134
PIXA * pixaBinSort(PIXA *pixas, l_int32 sorttype, l_int32 sortorder, NUMA **pnaindex, l_int32 copyflag)
pixaBinSort()
Definition: pixafunc1.c:1474
Definition: pix.h:719
l_ok pixZero(PIX *pix, l_int32 *pempty)
pixZero()
Definition: pix3.c:1701
l_ok pixaGetPixDimensions(PIXA *pixa, l_int32 index, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixaGetPixDimensions()
Definition: pixabasic.c:707
BOXA * boxaCreate(l_int32 n)
boxaCreate()
Definition: boxbasic.c:499
#define PIX_SRC
Definition: pix.h:327
PIX * pixCopy(PIX *pixd, PIX *pixs)
pixCopy()
Definition: pix1.c:628
PIXA * pixaSelectWithString(PIXA *pixas, const char *str, l_int32 *perror)
pixaSelectWithString()
Definition: pixafunc1.c:1193
PIXA * pixaClipToPix(PIXA *pixas, PIX *pixs)
pixaClipToPix()
Definition: pixafunc1.c:2520
void boxDestroy(BOX **pbox)
boxDestroy()
Definition: boxbasic.c:278
l_ok pixEqual(PIX *pix1, PIX *pix2, l_int32 *psame)
pixEqual()
Definition: compare.c:150
l_int32 boxaGetCount(BOXA *boxa)
boxaGetCount()
Definition: boxbasic.c:718
l_ok numaGetMax(NUMA *na, l_float32 *pmaxval, l_int32 *pimaxloc)
numaGetMax()
Definition: numafunc1.c:486
PIXA * pixaSelectRange(PIXA *pixas, l_int32 first, l_int32 last, l_int32 copyflag)
pixaSelectRange()
Definition: pixafunc1.c:1668
l_ok pixaAddBox(PIXA *pixa, BOX *box, l_int32 copyflag)
pixaAddBox()
Definition: pixabasic.c:547
PIX * pixTranslate(PIX *pixd, PIX *pixs, l_int32 hshift, l_int32 vshift, l_int32 incolor)
pixTranslate()
Definition: rop.c:431
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
PIX * pixScale(PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScale()
Definition: scale1.c:244
void pixaDestroy(PIXA **ppixa)
pixaDestroy()
Definition: pixabasic.c:408
BOX * boxCreate(l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxCreate()
Definition: boxbasic.c:165
l_ok pixCountConnComp(PIX *pixs, l_int32 connectivity, l_int32 *pcount)
pixCountConnComp()
Definition: conncomp.c:390
l_ok pixaClipToForeground(PIXA *pixas, PIXA **ppixad, BOXA **pboxa)
pixaClipToForeground()
Definition: pixafunc1.c:2569
l_int32 pixaGetCount(PIXA *pixa)
pixaGetCount()
Definition: pixabasic.c:631
PIX * pixAddBorderGeneral(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_uint32 val)
pixAddBorderGeneral()
Definition: pix2.c:1842
PIX * pixRotate(PIX *pixs, l_float32 angle, l_int32 type, l_int32 incolor, l_int32 width, l_int32 height)
pixRotate()
Definition: rotate.c:99
l_ok pixaReplacePix(PIXA *pixa, l_int32 index, PIX *pix, BOX *box)
pixaReplacePix()
Definition: pixabasic.c:1299
#define PIX_DST
Definition: pix.h:328
l_ok pixaAnyColormaps(PIXA *pixa, l_int32 *phascmap)
pixaAnyColormaps()
Definition: pixafunc1.c:2693
BOXA * pixaGetBoxa(PIXA *pixa, l_int32 accesstype)
pixaGetBoxa()
Definition: pixabasic.c:741