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. */
105static const l_int32 MinCompsForBinSort = 200;
106
107 /* Don't rotate any angle smaller than this */
108static 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
218PIX *
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{
227l_int32 w, h, empty, changed, count;
228BOXA *boxa;
229PIX *pixd;
230PIXA *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
305PIXA *
307 l_int32 width,
308 l_int32 height,
309 l_int32 type,
310 l_int32 relation,
311 l_int32 *pchanged)
312{
313NUMA *na;
314PIXA *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
361NUMA *
363 l_int32 width,
364 l_int32 height,
365 l_int32 type,
366 l_int32 relation)
367{
368l_int32 i, n, w, h, ival;
369NUMA *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;
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
452PIX *
454 l_float32 thresh,
455 l_int32 connectivity,
456 l_int32 type,
457 l_int32 *pchanged)
458{
459l_int32 w, h, empty, changed, count;
460BOXA *boxa;
461PIX *pixd;
462PIXA *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
526PIXA *
528 l_float32 thresh,
529 l_int32 type,
530 l_int32 *pchanged)
531{
532NUMA *na, *nai;
533PIXA *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
583PIX *
585 l_float32 thresh,
586 l_int32 connectivity,
587 l_int32 type,
588 l_int32 *pchanged)
589{
590l_int32 w, h, empty, changed, count;
591BOXA *boxa;
592PIX *pixd;
593PIXA *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
657PIXA *
659 l_float32 thresh,
660 l_int32 type,
661 l_int32 *pchanged)
662{
663NUMA *na, *nai;
664PIXA *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
713PIX *
715 l_float32 thresh,
716 l_int32 connectivity,
717 l_int32 type,
718 l_int32 *pchanged)
719{
720l_int32 w, h, empty, changed, count;
721BOXA *boxa;
722PIX *pixd;
723PIXA *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
791PIXA *
793 l_float32 thresh,
794 l_int32 type,
795 l_int32 *pchanged)
796{
797NUMA *na, *nai;
798PIXA *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
847PIX *
849 l_float32 thresh,
850 l_int32 connectivity,
851 l_int32 type,
852 l_int32 *pchanged)
853{
854l_int32 w, h, empty, changed, count;
855BOXA *boxa;
856PIX *pixd;
857PIXA *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
925PIXA *
927 l_float32 thresh,
928 l_int32 type,
929 l_int32 *pchanged)
930{
931NUMA *na, *nai;
932PIXA *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
980PIX *
982 l_float32 thresh,
983 l_int32 connectivity,
984 l_int32 type,
985 l_int32 *pchanged)
986{
987l_int32 w, h, empty, changed, count;
988BOXA *boxa;
989PIX *pixd;
990PIXA *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
1058PIXA *
1060 l_float32 thresh,
1061 l_int32 type,
1062 l_int32 *pchanged)
1063{
1064NUMA *na, *nai;
1065PIXA *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
1108PIXA *
1110 l_int32 nmin,
1111 l_int32 nmax,
1112 l_int32 connectivity,
1113 l_int32 *pchanged)
1114{
1115l_int32 n, i, count;
1116NUMA *na;
1117PIX *pix;
1118PIXA *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
1167PIXA *
1169 NUMA *na,
1170 l_int32 *pchanged)
1171{
1172l_int32 i, n, nbox, ival, nsave;
1173BOX *box;
1174PIX *pix1;
1175PIXA *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
1227l_ok
1229 PIXA *pixa,
1230 NUMA *na)
1231{
1232l_int32 i, n, ival, x, y, w, h;
1233BOX *box;
1234PIX *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
1280l_ok
1282 PIXA *pixa,
1283 NUMA *na)
1284{
1285l_int32 i, n, ival, x, y, w, h;
1286BOX *box;
1287PIX *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
1333PIXA *
1335 const char *str,
1336 l_int32 *perror)
1337{
1338l_int32 i, nval, npix, nbox, val, imaxval;
1339l_float32 maxval;
1340BOX *box;
1341NUMA *na;
1342PIX *pix1;
1343PIXA *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
1404PIX *
1406 PIXA *pixa,
1407 l_int32 index)
1408{
1409l_int32 n, x, y, w, h, same, maxd;
1410BOX *box;
1411BOXA *boxa;
1412PIX *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 *---------------------------------------------------------------------*/
1474PIXA *
1476 l_int32 sorttype,
1477 l_int32 sortorder,
1478 NUMA **pnaindex,
1479 l_int32 copyflag)
1480{
1481l_int32 i, n, nb, x, y, w, h;
1482BOXA *boxa;
1483NUMA *na, *naindex;
1484PIXA *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;
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
1614PIXA *
1616 l_int32 sorttype,
1617 l_int32 sortorder,
1618 NUMA **pnaindex,
1619 l_int32 copyflag)
1620{
1621l_int32 i, n, x, y, w, h;
1622BOXA *boxa;
1623NUMA *na, *naindex;
1624PIXA *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;
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
1702PIXA *
1704 NUMA *naindex,
1705 l_int32 copyflag)
1706{
1707l_int32 i, n, index;
1708BOX *box;
1709PIX *pix;
1710PIXA *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
1743PIXAA *
1745 NUMAA *naa,
1746 l_int32 copyflag)
1747{
1748l_int32 pixtot, ntot, i, j, n, nn, index;
1749BOX *box;
1750NUMA *na;
1751PIX *pix;
1752PIXA *pixa;
1753PIXAA *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 *---------------------------------------------------------------------*/
1808PIXA *
1810 l_int32 first,
1811 l_int32 last,
1812 l_int32 copyflag)
1813{
1814l_int32 n, npix, i;
1815PIX *pix;
1816PIXA *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
1863PIXAA *
1865 l_int32 first,
1866 l_int32 last,
1867 l_int32 copyflag)
1868{
1869l_int32 n, npixa, i;
1870PIXA *pixa;
1871PIXAA *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 *---------------------------------------------------------------------*/
1924PIXAA *
1926 l_int32 wd,
1927 l_int32 hd)
1928{
1929l_int32 n, i;
1930PIXA *pixa1, *pixa2;
1931PIXAA *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
1973PIXAA *
1975 NUMA *nawd,
1976 NUMA *nahd)
1977{
1978l_int32 n, i, wd, hd;
1979PIXA *pixa1, *pixa2;
1980PIXAA *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
2021PIXA *
2023 l_int32 wd,
2024 l_int32 hd)
2025{
2026l_int32 n, i;
2027PIX *pix1, *pix2;
2028PIXA *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
2066PIXA *
2068 l_int32 delw,
2069 l_int32 delh)
2070{
2071l_int32 n, i;
2072PIX *pix1, *pix2;
2073PIXA *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
2110PIXA *
2112 l_float32 scalex,
2113 l_float32 scaley)
2114{
2115l_int32 i, n, nb;
2116BOXA *boxa1, *boxa2;
2117PIX *pix1, *pix2;
2118PIXA *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
2161PIXA *
2163 l_float32 scalex,
2164 l_float32 scaley)
2165{
2166l_int32 i, n, nb;
2167BOXA *boxa1, *boxa2;
2168PIX *pix1, *pix2;
2169PIXA *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 *---------------------------------------------------------------------*/
2226PIXA *
2228 l_float32 angle,
2229 l_int32 type,
2230 l_int32 incolor,
2231 l_int32 width,
2232 l_int32 height)
2233{
2234l_int32 i, n;
2235BOXA *boxa;
2236PIX *pixs, *pixd;
2237PIXA *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
2284PIXA *
2286 l_int32 rotation)
2287{
2288l_int32 i, n, nb, w, h;
2289BOX *boxs, *boxd;
2290PIX *pixs, *pixd;
2291PIXA *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
2336PIXA *
2338 l_int32 hshift,
2339 l_int32 vshift,
2340 l_int32 incolor)
2341{
2342l_int32 i, n, nb;
2343BOXA *boxas, *boxad;
2344PIX *pixs, *pixd;
2345PIXA *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 *---------------------------------------------------------------------*/
2410PIXA *
2412 PIXA *pixas,
2413 l_int32 left,
2414 l_int32 right,
2415 l_int32 top,
2416 l_int32 bot,
2417 l_uint32 val)
2418{
2419l_int32 i, n, nbox;
2420BOX *box;
2421BOXA *boxad;
2422PIX *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
2481PIXA *
2483 NUMA **pnaindex,
2484 l_int32 copyflag)
2485{
2486l_int32 i, j, m, mb, n;
2487BOX *box;
2488NUMA *naindex;
2489PIX *pix;
2490PIXA *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
2536l_ok
2538 l_int32 *pminw,
2539 l_int32 *pminh,
2540 l_int32 *pmaxw,
2541 l_int32 *pmaxh)
2542{
2543l_int32 minw, minh, maxw, maxh, minpw, minph, maxpw, maxph, i, n;
2544PIXA *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
2590l_ok
2592 l_int32 *pminw,
2593 l_int32 *pminh,
2594 l_int32 *pmaxw,
2595 l_int32 *pmaxh)
2596{
2597l_int32 minw, minh, maxw, maxh, i, n, w, h;
2598PIX *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
2660PIXA *
2662 PIX *pixs)
2663{
2664l_int32 i, n;
2665BOX *box;
2666PIX *pix, *pixc;
2667PIXA *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
2709l_ok
2711 PIXA **ppixad,
2712 BOXA **pboxa)
2713{
2714l_int32 i, n;
2715BOX *box1;
2716PIX *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
2766l_ok
2768 l_int32 *pdepth)
2769{
2770l_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
2803l_ok
2805 l_int32 *phascolor)
2806{
2807l_int32 i, n, hascolor, d;
2808PIX *pix;
2809PIXCMAP *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
2844l_ok
2846 l_int32 *phascmap)
2847{
2848l_int32 i, n;
2849PIX *pix;
2850PIXCMAP *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
2883l_ok
2885 l_int32 *pmaxdepth,
2886 l_int32 *psame)
2887{
2888l_int32 i, n, d, d0;
2889l_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
2936PIXA *
2938{
2939l_int32 i, n, depth, same, hascmap, maxdepth;
2940BOXA *boxa;
2941PIX *pix1, *pix2;
2942PIXA *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
3008PIXA *
3010 l_int32 depth)
3011{
3012l_int32 i, n, maxd;
3013BOXA *boxa;
3014PIX *pix1, *pix2;
3015PIXA *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
3081l_ok
3083 PIXA *pixa2,
3084 l_int32 maxdist,
3085 NUMA **pnaindex,
3086 l_int32 *psame)
3087{
3088l_int32 i, j, n, empty1, empty2, same, sameboxa;
3089BOXA *boxa1, *boxa2;
3090NUMA *na;
3091PIX *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
3165l_ok
3167{
3168l_int32 i, n, w, h;
3169BOX *box;
3170BOXA *boxa;
3171PIX *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
BOX * boxaGetBox(BOXA *boxa, l_int32 index, l_int32 accessflag)
boxaGetBox()
Definition: boxbasic.c:779
void boxDestroy(BOX **pbox)
boxDestroy()
Definition: boxbasic.c:282
BOX * boxCreate(l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxCreate()
Definition: boxbasic.c:172
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
BOXA * boxaCreate(l_int32 n)
boxaCreate()
Definition: boxbasic.c:502
l_ok boxaAddBox(BOXA *boxa, BOX *box, l_int32 copyflag)
boxaAddBox()
Definition: boxbasic.c:620
void boxaDestroy(BOXA **pboxa)
boxaDestroy()
Definition: boxbasic.c:583
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 * numaaGetNuma(NUMAA *naa, l_int32 index, l_int32 accessflag)
numaaGetNuma()
Definition: numabasic.c:1740
l_int32 numaaGetCount(NUMAA *naa)
numaaGetCount()
Definition: numabasic.c:1631
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 * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:194
NUMA * numaCreateFromString(const char *str)
numaCreateFromString()
Definition: numabasic.c:315
NUMA * numaMakeThresholdIndicator(NUMA *nas, l_float32 thresh, l_int32 type)
numaMakeThresholdIndicator()
Definition: numafunc1.c:1231
NUMA * numaGetBinSortIndex(NUMA *nas, l_int32 sortorder)
numaGetBinSortIndex()
Definition: numafunc1.c:2833
l_ok numaGetMax(NUMA *na, l_float32 *pmaxval, l_int32 *pimaxloc)
numaGetMax()
Definition: numafunc1.c:496
NUMA * numaGetSortIndex(NUMA *na, l_int32 sortorder)
numaGetSortIndex()
Definition: numafunc1.c:2751
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 * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:593
PIX * pixCreateTemplate(const PIX *pixs)
pixCreateTemplate()
Definition: pix1.c:383
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:315
l_ok pixCopyColormap(PIX *pixd, const PIX *pixs)
pixCopyColormap()
Definition: pix1.c:816
PIX * pixCopy(PIX *pixd, const PIX *pixs)
pixCopy()
Definition: pix1.c:705
PIX * pixAddBorderGeneral(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_uint32 val)
pixAddBorderGeneral()
Definition: pix2.c:1917
NUMA * pixaCountPixels(PIXA *pixa)
pixaCountPixels()
Definition: pix3.c:1892
l_ok pixZero(PIX *pix, l_int32 *pempty)
pixZero()
Definition: pix3.c:1815
PIX * pixAnd(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixAnd()
Definition: pix3.c:1624
NUMA * pixaFindWidthHeightRatio(PIXA *pixa)
pixaFindWidthHeightRatio()
Definition: pix5.c:670
PIX * pixClipRectangle(PIX *pixs, BOX *box, BOX **pboxc)
pixClipRectangle()
Definition: pix5.c:1026
NUMA * pixaFindPerimToAreaRatio(PIXA *pixa)
pixaFindPerimToAreaRatio()
Definition: pix5.c:241
NUMA * pixaFindAreaFraction(PIXA *pixa)
pixaFindAreaFraction()
Definition: pix5.c:441
l_ok pixClipToForeground(PIX *pixs, PIX **ppixd, BOX **pbox)
pixClipToForeground()
Definition: pix5.c:1784
NUMA * pixaFindPerimSizeRatio(PIXA *pixa)
pixaFindPerimSizeRatio()
Definition: pix5.c:345
#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
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
l_int32 pixaGetBoxaCount(PIXA *pixa)
pixaGetBoxaCount()
Definition: pixabasic.c:784
BOX * pixaGetBox(PIXA *pixa, l_int32 index, l_int32 accesstype)
pixaGetBox()
Definition: pixabasic.c:816
l_ok pixaaAddPixa(PIXAA *paa, PIXA *pixa, l_int32 copyflag)
pixaaAddPixa()
Definition: pixabasic.c:1998
l_ok pixaGetPixDimensions(PIXA *pixa, l_int32 index, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixaGetPixDimensions()
Definition: pixabasic.c:726
PIXA * pixaaGetPixa(PIXAA *paa, l_int32 index, l_int32 accesstype)
pixaaGetPixa()
Definition: pixabasic.c:2206
PIXA * pixaCreate(l_int32 n)
pixaCreate()
Definition: pixabasic.c:167
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
PIX * pixaGetPix(PIXA *pixa, l_int32 index, l_int32 accesstype)
pixaGetPix()
Definition: pixabasic.c:691
l_int32 pixaaGetCount(PIXAA *paa, NUMA **pna)
pixaaGetCount()
Definition: pixabasic.c:2157
PIXAA * pixaaCreate(l_int32 n)
pixaaCreate()
Definition: pixabasic.c:1852
BOXA * pixaGetBoxa(PIXA *pixa, l_int32 accesstype)
pixaGetBoxa()
Definition: pixabasic.c:760
PIXA * pixaCopy(PIXA *pixa, l_int32 copyflag)
pixaCopy()
Definition: pixabasic.c:453
l_ok pixaSetBoxa(PIXA *pixa, BOXA *boxa, l_int32 accesstype)
pixaSetBoxa()
Definition: pixabasic.c:896
l_ok pixaGetRenderingDepth(PIXA *pixa, l_int32 *pdepth)
pixaGetRenderingDepth()
Definition: pixafunc1.c:2767
PIXA * pixaSelectByNumConnComp(PIXA *pixas, l_int32 nmin, l_int32 nmax, l_int32 connectivity, l_int32 *pchanged)
pixaSelectByNumConnComp()
Definition: pixafunc1.c:1109
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 pixaHasColor(PIXA *pixa, l_int32 *phascolor)
pixaHasColor()
Definition: pixafunc1.c:2804
PIXA * pixaSelectByPerimToAreaRatio(PIXA *pixas, l_float32 thresh, l_int32 type, l_int32 *pchanged)
pixaSelectByPerimToAreaRatio()
Definition: pixafunc1.c:527
l_ok pixaSizeRange(PIXA *pixa, l_int32 *pminw, l_int32 *pminh, l_int32 *pmaxw, l_int32 *pmaxh)
pixaSizeRange()
Definition: pixafunc1.c:2591
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 * pixaSelectByAreaFraction(PIXA *pixas, l_float32 thresh, l_int32 type, l_int32 *pchanged)
pixaSelectByAreaFraction()
Definition: pixafunc1.c:792
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
PIXAA * pixaaSelectRange(PIXAA *paas, l_int32 first, l_int32 last, l_int32 copyflag)
pixaaSelectRange()
Definition: pixafunc1.c:1864
PIXAA * pixaaScaleToSizeVar(PIXAA *paas, NUMA *nawd, NUMA *nahd)
pixaaScaleToSizeVar()
Definition: pixafunc1.c:1974
PIXA * pixaSelectByWidthHeightRatio(PIXA *pixas, l_float32 thresh, l_int32 type, l_int32 *pchanged)
pixaSelectByWidthHeightRatio()
Definition: pixafunc1.c:1059
l_ok pixaAnyColormaps(PIXA *pixa, l_int32 *phascmap)
pixaAnyColormaps()
Definition: pixafunc1.c:2845
PIXA * pixaaFlattenToPixa(PIXAA *paa, NUMA **pnaindex, l_int32 copyflag)
pixaaFlattenToPixa()
Definition: pixafunc1.c:2482
PIXA * pixaSelectWithIndicator(PIXA *pixas, NUMA *na, l_int32 *pchanged)
pixaSelectWithIndicator()
Definition: pixafunc1.c:1168
PIXA * pixaSelectRange(PIXA *pixas, l_int32 first, l_int32 last, l_int32 copyflag)
pixaSelectRange()
Definition: pixafunc1.c:1809
PIXA * pixaConvertToGivenDepth(PIXA *pixas, l_int32 depth)
pixaConvertToGivenDepth()
Definition: pixafunc1.c:3009
PIXA * pixaSelectByPerimSizeRatio(PIXA *pixas, l_float32 thresh, l_int32 type, l_int32 *pchanged)
pixaSelectByPerimSizeRatio()
Definition: pixafunc1.c:658
PIX * pixSelectByWidthHeightRatio(PIX *pixs, l_float32 thresh, l_int32 connectivity, l_int32 type, l_int32 *pchanged)
pixSelectByWidthHeightRatio()
Definition: pixafunc1.c:981
l_ok pixRemoveWithIndicator(PIX *pixs, PIXA *pixa, NUMA *na)
pixRemoveWithIndicator()
Definition: pixafunc1.c:1228
PIXA * pixaScaleToSize(PIXA *pixas, l_int32 wd, l_int32 hd)
pixaScaleToSize()
Definition: pixafunc1.c:2022
l_ok pixAddWithIndicator(PIX *pixs, PIXA *pixa, NUMA *na)
pixAddWithIndicator()
Definition: pixafunc1.c:1281
PIXA * pixaConvertToSameDepth(PIXA *pixas)
pixaConvertToSameDepth()
Definition: pixafunc1.c:2937
PIXA * pixaTranslate(PIXA *pixas, l_int32 hshift, l_int32 vshift, l_int32 incolor)
pixaTranslate()
Definition: pixafunc1.c:2337
PIXA * pixaSelectBySize(PIXA *pixas, l_int32 width, l_int32 height, l_int32 type, l_int32 relation, l_int32 *pchanged)
pixaSelectBySize()
Definition: pixafunc1.c:306
l_ok pixaClipToForeground(PIXA *pixas, PIXA **ppixad, BOXA **pboxa)
pixaClipToForeground()
Definition: pixafunc1.c:2710
PIXA * pixaRotateOrth(PIXA *pixas, l_int32 rotation)
pixaRotateOrth()
Definition: pixafunc1.c:2285
l_ok pixaGetDepthInfo(PIXA *pixa, l_int32 *pmaxdepth, l_int32 *psame)
pixaGetDepthInfo()
Definition: pixafunc1.c:2884
PIX * pixSelectByPerimToAreaRatio(PIX *pixs, l_float32 thresh, l_int32 connectivity, l_int32 type, l_int32 *pchanged)
pixSelectByPerimToAreaRatio()
Definition: pixafunc1.c:453
PIXA * pixaBinSort(PIXA *pixas, l_int32 sorttype, l_int32 sortorder, NUMA **pnaindex, l_int32 copyflag)
pixaBinSort()
Definition: pixafunc1.c:1615
PIX * pixaRenderComponent(PIX *pixs, PIXA *pixa, l_int32 index)
pixaRenderComponent()
Definition: pixafunc1.c:1405
PIXA * pixaSelectWithString(PIXA *pixas, const char *str, l_int32 *perror)
pixaSelectWithString()
Definition: pixafunc1.c:1334
PIXA * pixaScale(PIXA *pixas, l_float32 scalex, l_float32 scaley)
pixaScale()
Definition: pixafunc1.c:2111
PIXA * pixaSortByIndex(PIXA *pixas, NUMA *naindex, l_int32 copyflag)
pixaSortByIndex()
Definition: pixafunc1.c:1703
PIXAA * pixaSort2dByIndex(PIXA *pixas, NUMAA *naa, l_int32 copyflag)
pixaSort2dByIndex()
Definition: pixafunc1.c:1744
l_ok pixaEqual(PIXA *pixa1, PIXA *pixa2, l_int32 maxdist, NUMA **pnaindex, l_int32 *psame)
pixaEqual()
Definition: pixafunc1.c:3082
PIX * pixSelectByArea(PIX *pixs, l_float32 thresh, l_int32 connectivity, l_int32 type, l_int32 *pchanged)
pixSelectByArea()
Definition: pixafunc1.c:848
PIXA * pixaSort(PIXA *pixas, l_int32 sorttype, l_int32 sortorder, NUMA **pnaindex, l_int32 copyflag)
pixaSort()
Definition: pixafunc1.c:1475
PIXA * pixaSelectByArea(PIXA *pixas, l_float32 thresh, l_int32 type, l_int32 *pchanged)
pixaSelectByArea()
Definition: pixafunc1.c:926
PIXAA * pixaaScaleToSize(PIXAA *paas, l_int32 wd, l_int32 hd)
pixaaScaleToSize()
Definition: pixafunc1.c:1925
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
NUMA * pixaMakeSizeIndicator(PIXA *pixa, l_int32 width, l_int32 height, l_int32 type, l_int32 relation)
pixaMakeSizeIndicator()
Definition: pixafunc1.c:362
PIXA * pixaScaleToSizeRel(PIXA *pixas, l_int32 delw, l_int32 delh)
pixaScaleToSizeRel()
Definition: pixafunc1.c:2067
PIXA * pixaScaleBySampling(PIXA *pixas, l_float32 scalex, l_float32 scaley)
pixaScaleBySampling()
Definition: pixafunc1.c:2162
PIXA * pixaClipToPix(PIXA *pixas, PIX *pixs)
pixaClipToPix()
Definition: pixafunc1.c:2661
PIX * pixSelectByAreaFraction(PIX *pixs, l_float32 thresh, l_int32 connectivity, l_int32 type, l_int32 *pchanged)
pixSelectByAreaFraction()
Definition: pixafunc1.c:714
PIX * pixSelectByPerimSizeRatio(PIX *pixs, l_float32 thresh, l_int32 connectivity, l_int32 type, l_int32 *pchanged)
pixSelectByPerimSizeRatio()
Definition: pixafunc1.c:584
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 * pixScaleBySampling(PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScaleBySampling()
Definition: scale1.c:1338
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
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