Leptonica 1.82.0
Image processing and image analysis suite
pixafunc2.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
159#ifdef HAVE_CONFIG_H
160#include <config_auto.h>
161#endif /* HAVE_CONFIG_H */
162
163#include <string.h>
164#include <math.h> /* for sqrt() */
165#include "allheaders.h"
166
167/*---------------------------------------------------------------------*
168 * Pixa Display *
169 *---------------------------------------------------------------------*/
190PIX *
192 l_int32 w,
193 l_int32 h)
194{
195l_int32 i, n, d, xb, yb, wb, hb, res;
196BOXA *boxa;
197PIX *pix1, *pixd;
198
199 PROCNAME("pixaDisplay");
200
201 if (!pixa)
202 return (PIX *)ERROR_PTR("pixa not defined", procName, NULL);
203
204 n = pixaGetCount(pixa);
205 if (n == 0 && w == 0 && h == 0)
206 return (PIX *)ERROR_PTR("no components; no size", procName, NULL);
207 if (n == 0) {
208 L_WARNING("no components; returning empty 1 bpp pix\n", procName);
209 return pixCreate(w, h, 1);
210 }
211
212 /* If w and h not input, determine the minimum size required
213 * to contain the origin and all c.c. */
214 if (w == 0 || h == 0) {
215 boxa = pixaGetBoxa(pixa, L_CLONE);
216 boxaGetExtent(boxa, &w, &h, NULL);
217 boxaDestroy(&boxa);
218 if (w == 0 || h == 0)
219 return (PIX *)ERROR_PTR("no associated boxa", procName, NULL);
220 }
221
222 /* Use the first pix in pixa to determine depth and resolution */
223 pix1 = pixaGetPix(pixa, 0, L_CLONE);
224 d = pixGetDepth(pix1);
225 res = pixGetXRes(pix1);
226 pixDestroy(&pix1);
227
228 if ((pixd = pixCreate(w, h, d)) == NULL)
229 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
230 pixSetResolution(pixd, res, res);
231 if (d > 1)
232 pixSetAll(pixd);
233 for (i = 0; i < n; i++) {
234 if (pixaGetBoxGeometry(pixa, i, &xb, &yb, &wb, &hb)) {
235 L_WARNING("no box found!\n", procName);
236 continue;
237 }
238 pix1 = pixaGetPix(pixa, i, L_CLONE);
239 if (d == 1)
240 pixRasterop(pixd, xb, yb, wb, hb, PIX_PAINT, pix1, 0, 0);
241 else
242 pixRasterop(pixd, xb, yb, wb, hb, PIX_SRC, pix1, 0, 0);
243 pixDestroy(&pix1);
244 }
245
246 return pixd;
247}
248
249
268PIX *
270 l_int32 w,
271 l_int32 h)
272{
273l_int32 i, n, same, maxd, index, xb, yb, wb, hb, res;
274BOXA *boxa;
275PIX *pixs, *pix1, *pixd;
276PIXCMAP *cmap;
277
278 PROCNAME("pixaDisplayRandomCmap");
279
280 if (!pixa)
281 return (PIX *)ERROR_PTR("pixa not defined", procName, NULL);
282
283 if ((n = pixaGetCount(pixa)) == 0)
284 return (PIX *)ERROR_PTR("no components", procName, NULL);
285 pixaVerifyDepth(pixa, &same, &maxd);
286 if (maxd > 1)
287 return (PIX *)ERROR_PTR("not all components are 1 bpp", procName, NULL);
288
289 /* If w and h are not input, determine the minimum size required
290 * to contain the origin and all c.c. */
291 if (w == 0 || h == 0) {
292 boxa = pixaGetBoxa(pixa, L_CLONE);
293 boxaGetExtent(boxa, &w, &h, NULL);
294 boxaDestroy(&boxa);
295 }
296
297 /* Set up an 8 bpp dest pix, with a colormap with 254 random colors */
298 if ((pixd = pixCreate(w, h, 8)) == NULL)
299 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
300 cmap = pixcmapCreateRandom(8, 1, 1);
301 pixSetColormap(pixd, cmap);
302
303 /* Color each component and blit it in */
304 for (i = 0; i < n; i++) {
305 index = 1 + (i % 254);
306 pixaGetBoxGeometry(pixa, i, &xb, &yb, &wb, &hb);
307 pixs = pixaGetPix(pixa, i, L_CLONE);
308 if (i == 0) res = pixGetXRes(pixs);
309 pix1 = pixConvert1To8(NULL, pixs, 0, index);
310 pixRasterop(pixd, xb, yb, wb, hb, PIX_PAINT, pix1, 0, 0);
311 pixDestroy(&pixs);
312 pixDestroy(&pix1);
313 }
314
315 pixSetResolution(pixd, res, res);
316 return pixd;
317}
318
319
342PIX *
344 l_int32 direction,
345 l_float32 scalefactor,
346 l_int32 background, /* not used */
347 l_int32 spacing,
348 l_int32 border,
349 BOXA **pboxa)
350{
351l_int32 i, n, x, y, w, h, size, depth, bordval;
352BOX *box;
353PIX *pix1, *pix2, *pix3, *pixd;
354PIXA *pixa1, *pixa2;
355
356 PROCNAME("pixaDisplayLinearly");
357
358 if (pboxa) *pboxa = NULL;
359 if (!pixas)
360 return (PIX *)ERROR_PTR("pixas not defined", procName, NULL);
361 if (direction != L_HORIZ && direction != L_VERT)
362 return (PIX *)ERROR_PTR("invalid direction", procName, NULL);
363
364 /* Make sure all pix are at the same depth */
365 pixa1 = pixaConvertToSameDepth(pixas);
366 pixaGetDepthInfo(pixa1, &depth, NULL);
367
368 /* Scale and add border if requested */
369 n = pixaGetCount(pixa1);
370 pixa2 = pixaCreate(n);
371 bordval = (depth == 1) ? 1 : 0;
372 size = (n - 1) * spacing;
373 x = y = 0;
374 for (i = 0; i < n; i++) {
375 if ((pix1 = pixaGetPix(pixa1, i, L_CLONE)) == NULL) {
376 L_WARNING("missing pix at index %d\n", procName, i);
377 continue;
378 }
379
380 if (scalefactor != 1.0)
381 pix2 = pixScale(pix1, scalefactor, scalefactor);
382 else
383 pix2 = pixClone(pix1);
384 if (border)
385 pix3 = pixAddBorder(pix2, border, bordval);
386 else
387 pix3 = pixClone(pix2);
388
389 pixGetDimensions(pix3, &w, &h, NULL);
390 box = boxCreate(x, y, w, h);
391 if (direction == L_HORIZ) {
392 size += w;
393 x += w + spacing;
394 } else { /* vertical */
395 size += h;
396 y += h + spacing;
397 }
398 pixaAddPix(pixa2, pix3, L_INSERT);
399 pixaAddBox(pixa2, box, L_INSERT);
400 pixDestroy(&pix1);
401 pixDestroy(&pix2);
402 }
403 pixd = pixaDisplay(pixa2, 0, 0);
404
405 if (pboxa)
406 *pboxa = pixaGetBoxa(pixa2, L_COPY);
407 pixaDestroy(&pixa1);
408 pixaDestroy(&pixa2);
409 return pixd;
410}
411
412
439PIX *
441 l_int32 cellw,
442 l_int32 cellh,
443 l_int32 *pncols,
444 BOXA **pboxa)
445{
446char buf[16];
447l_int32 n, nw, nh, w, h, d, wt, ht, res, samedepth;
448l_int32 index, i, j, hascmap;
449BOX *box;
450BOXA *boxa;
451PIX *pix1, *pix2, *pixd;
452PIXA *pixa1;
453
454 PROCNAME("pixaDisplayOnLattice");
455
456 if (pncols) *pncols = 0;
457 if (pboxa) *pboxa = NULL;
458 if (!pixa)
459 return (PIX *)ERROR_PTR("pixa not defined", procName, NULL);
460
461 /* If any pix have colormaps, or if the depths differ, generate rgb */
462 if ((n = pixaGetCount(pixa)) == 0)
463 return (PIX *)ERROR_PTR("no components", procName, NULL);
464 pixaAnyColormaps(pixa, &hascmap);
465 pixaVerifyDepth(pixa, &samedepth, NULL);
466 if (hascmap || !samedepth) {
467 pixa1 = pixaCreate(n);
468 for (i = 0; i < n; i++) {
469 pix1 = pixaGetPix(pixa, i, L_CLONE);
470 pix2 = pixConvertTo32(pix1);
471 pixaAddPix(pixa1, pix2, L_INSERT);
472 pixDestroy(&pix1);
473 }
474 } else {
475 pixa1 = pixaCopy(pixa, L_CLONE);
476 }
477
478 /* Have number of rows and columns approximately equal */
479 nw = (l_int32)sqrt((l_float64)n);
480 nh = (n + nw - 1) / nw;
481 w = cellw * nw;
482 h = cellh * nh;
483
484 /* Use the first pix to determine output depth and resolution */
485 pix1 = pixaGetPix(pixa1, 0, L_CLONE);
486 d = pixGetDepth(pix1);
487 res = pixGetXRes(pix1);
488 pixDestroy(&pix1);
489 if ((pixd = pixCreate(w, h, d)) == NULL) {
490 pixaDestroy(&pixa1);
491 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
492 }
494 pixSetResolution(pixd, res, res);
495 boxa = boxaCreate(n);
496
497 /* Tile the output */
498 index = 0;
499 for (i = 0; i < nh; i++) {
500 for (j = 0; j < nw && index < n; j++, index++) {
501 pix1 = pixaGetPix(pixa1, index, L_CLONE);
502 pixGetDimensions(pix1, &wt, &ht, NULL);
503 if (wt > cellw || ht > cellh) {
504 L_INFO("pix(%d) omitted; size %dx%x\n", procName, index,
505 wt, ht);
506 box = boxCreate(0, 0, 0, 0);
507 boxaAddBox(boxa, box, L_INSERT);
508 pixDestroy(&pix1);
509 continue;
510 }
511 pixRasterop(pixd, j * cellw, i * cellh, wt, ht,
512 PIX_SRC, pix1, 0, 0);
513 box = boxCreate(j * cellw, i * cellh, wt, ht);
514 boxaAddBox(boxa, box, L_INSERT);
515 pixDestroy(&pix1);
516 }
517 }
518
519 /* Save the number of tiles in the text field */
520 snprintf(buf, sizeof(buf), "n = %d", boxaGetCount(boxa));
521 pixSetText(pixd, buf);
522
523 if (pncols) *pncols = nw;
524 if (pboxa)
525 *pboxa = boxa;
526 else
527 boxaDestroy(&boxa);
528 pixaDestroy(&pixa1);
529 return pixd;
530}
531
532
556PIX *
558 l_int32 nx,
559 l_int32 ny,
560 l_int32 borderwidth,
561 l_uint32 bordercolor)
562{
563l_int32 w, h, d, wt, ht;
564l_int32 i, j, k, x, y, n;
565PIX *pix1, *pixd;
566
567 PROCNAME("pixaDisplayUnsplit");
568
569 if (!pixa)
570 return (PIX *)ERROR_PTR("pixa not defined", procName, NULL);
571 if (nx <= 0 || ny <= 0)
572 return (PIX *)ERROR_PTR("nx and ny must be > 0", procName, NULL);
573 if ((n = pixaGetCount(pixa)) == 0)
574 return (PIX *)ERROR_PTR("no components", procName, NULL);
575 if (n != nx * ny)
576 return (PIX *)ERROR_PTR("n != nx * ny", procName, NULL);
577 borderwidth = L_MAX(0, borderwidth);
578
579 pixaGetPixDimensions(pixa, 0, &wt, &ht, &d);
580 w = nx * (wt + 2 * borderwidth);
581 h = ny * (ht + 2 * borderwidth);
582
583 if ((pixd = pixCreate(w, h, d)) == NULL)
584 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
585 pix1 = pixaGetPix(pixa, 0, L_CLONE);
586 pixCopyColormap(pixd, pix1);
587 pixDestroy(&pix1);
588 if (borderwidth > 0)
589 pixSetAllArbitrary(pixd, bordercolor);
590
591 y = borderwidth;
592 for (i = 0, k = 0; i < ny; i++) {
593 x = borderwidth;
594 for (j = 0; j < nx; j++, k++) {
595 pix1 = pixaGetPix(pixa, k, L_CLONE);
596 pixRasterop(pixd, x, y, wt, ht, PIX_SRC, pix1, 0, 0);
597 pixDestroy(&pix1);
598 x += wt + 2 * borderwidth;
599 }
600 y += ht + 2 * borderwidth;
601 }
602
603 return pixd;
604}
605
606
631PIX *
633 l_int32 maxwidth,
634 l_int32 background,
635 l_int32 spacing)
636{
637l_int32 wmax, hmax, wd, hd, d, hascmap, res, same;
638l_int32 i, j, n, ni, ncols, nrows;
639l_int32 ystart, xstart, wt, ht;
640PIX *pix1, *pix2, *pixd;
641PIXA *pixa1;
642
643 PROCNAME("pixaDisplayTiled");
644
645 if (!pixa)
646 return (PIX *)ERROR_PTR("pixa not defined", procName, NULL);
647 spacing = L_MAX(spacing, 0);
648 if ((n = pixaGetCount(pixa)) == 0)
649 return (PIX *)ERROR_PTR("no components", procName, NULL);
650
651 /* If any pix have colormaps, generate rgb */
652 pixaAnyColormaps(pixa, &hascmap);
653 if (hascmap) {
654 pixa1 = pixaCreate(n);
655 for (i = 0; i < n; i++) {
656 pix1 = pixaGetPix(pixa, i, L_CLONE);
657 pix2 = pixConvertTo32(pix1);
658 pixaAddPix(pixa1, pix2, L_INSERT);
659 pixDestroy(&pix1);
660 }
661 } else {
662 pixa1 = pixaCopy(pixa, L_CLONE);
663 }
664
665 /* Find the max dimensions and depth subimages */
666 pixaGetDepthInfo(pixa1, &d, &same);
667 if (!same) {
668 pixaDestroy(&pixa1);
669 return (PIX *)ERROR_PTR("depths not equal", procName, NULL);
670 }
671 pixaSizeRange(pixa1, NULL, NULL, &wmax, &hmax);
672
673 /* Get the number of rows and columns and the output image size */
674 ncols = (l_int32)((l_float32)(maxwidth - spacing) /
675 (l_float32)(wmax + spacing));
676 ncols = L_MAX(ncols, 1);
677 nrows = (n + ncols - 1) / ncols;
678 wd = wmax * ncols + spacing * (ncols + 1);
679 hd = hmax * nrows + spacing * (nrows + 1);
680 if ((pixd = pixCreate(wd, hd, d)) == NULL) {
681 pixaDestroy(&pixa1);
682 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
683 }
684
685 /* Reset the background color if necessary */
686 if ((background == 1 && d == 1) || (background == 0 && d != 1))
687 pixSetAll(pixd);
688
689 /* Blit the images to the dest */
690 for (i = 0, ni = 0; i < nrows; i++) {
691 ystart = spacing + i * (hmax + spacing);
692 for (j = 0; j < ncols && ni < n; j++, ni++) {
693 xstart = spacing + j * (wmax + spacing);
694 pix1 = pixaGetPix(pixa1, ni, L_CLONE);
695 if (ni == 0) res = pixGetXRes(pix1);
696 pixGetDimensions(pix1, &wt, &ht, NULL);
697 pixRasterop(pixd, xstart, ystart, wt, ht, PIX_SRC, pix1, 0, 0);
698 pixDestroy(&pix1);
699 }
700 }
701 pixSetResolution(pixd, res, res);
702
703 pixaDestroy(&pixa1);
704 return pixd;
705}
706
707
745PIX *
747 l_int32 outdepth,
748 l_int32 maxwidth,
749 l_float32 scalefactor,
750 l_int32 background,
751 l_int32 spacing,
752 l_int32 border)
753{
754l_int32 h; /* cumulative height over all the rows */
755l_int32 w; /* cumulative height in the current row */
756l_int32 bordval, wtry, wt, ht;
757l_int32 irow; /* index of current pix in current row */
758l_int32 wmaxrow; /* width of the largest row */
759l_int32 maxh; /* max height in row */
760l_int32 i, j, index, n, x, y, nrows, ninrow, res;
761size_t size;
762l_uint8 *data;
763BOXA *boxa;
764NUMA *nainrow; /* number of pix in the row */
765NUMA *namaxh; /* height of max pix in the row */
766PIX *pix, *pixn, *pix1, *pixd;
767PIXA *pixan;
768
769 PROCNAME("pixaDisplayTiledInRows");
770
771 if (!pixa)
772 return (PIX *)ERROR_PTR("pixa not defined", procName, NULL);
773 if (outdepth != 1 && outdepth != 8 && outdepth != 32)
774 return (PIX *)ERROR_PTR("outdepth not in {1, 8, 32}", procName, NULL);
775 spacing = L_MAX(spacing, 0);
776 border = L_MAX(border, 0);
777 if (scalefactor <= 0.0) scalefactor = 1.0;
778
779 if ((n = pixaGetCount(pixa)) == 0)
780 return (PIX *)ERROR_PTR("no components", procName, NULL);
781
782 /* Normalize depths, scale, remove colormaps; optionally add border */
783 pixan = pixaCreate(n);
784 bordval = (outdepth == 1) ? 1 : 0;
785 for (i = 0; i < n; i++) {
786 if ((pix = pixaGetPix(pixa, i, L_CLONE)) == NULL)
787 continue;
788
789 if (outdepth == 1)
790 pixn = pixConvertTo1(pix, 128);
791 else if (outdepth == 8)
792 pixn = pixConvertTo8(pix, FALSE);
793 else /* outdepth == 32 */
794 pixn = pixConvertTo32(pix);
795 pixDestroy(&pix);
796
797 if (scalefactor != 1.0)
798 pix1 = pixScale(pixn, scalefactor, scalefactor);
799 else
800 pix1 = pixClone(pixn);
801 if (border)
802 pixd = pixAddBorder(pix1, border, bordval);
803 else
804 pixd = pixClone(pix1);
805 pixDestroy(&pixn);
806 pixDestroy(&pix1);
807
808 pixaAddPix(pixan, pixd, L_INSERT);
809 }
810 if (pixaGetCount(pixan) != n) {
811 n = pixaGetCount(pixan);
812 L_WARNING("only got %d components\n", procName, n);
813 if (n == 0) {
814 pixaDestroy(&pixan);
815 return (PIX *)ERROR_PTR("no components", procName, NULL);
816 }
817 }
818
819 /* Compute parameters for layout */
820 nainrow = numaCreate(0);
821 namaxh = numaCreate(0);
822 wmaxrow = 0;
823 w = h = spacing;
824 maxh = 0; /* max height in row */
825 for (i = 0, irow = 0; i < n; i++, irow++) {
826 pixaGetPixDimensions(pixan, i, &wt, &ht, NULL);
827 wtry = w + wt + spacing;
828 if (wtry > maxwidth) { /* end the current row and start next one */
829 numaAddNumber(nainrow, irow);
830 numaAddNumber(namaxh, maxh);
831 wmaxrow = L_MAX(wmaxrow, w);
832 h += maxh + spacing;
833 irow = 0;
834 w = wt + 2 * spacing;
835 maxh = ht;
836 } else {
837 w = wtry;
838 maxh = L_MAX(maxh, ht);
839 }
840 }
841
842 /* Enter the parameters for the last row */
843 numaAddNumber(nainrow, irow);
844 numaAddNumber(namaxh, maxh);
845 wmaxrow = L_MAX(wmaxrow, w);
846 h += maxh + spacing;
847
848 if ((pixd = pixCreate(wmaxrow, h, outdepth)) == NULL) {
849 numaDestroy(&nainrow);
850 numaDestroy(&namaxh);
851 pixaDestroy(&pixan);
852 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
853 }
854
855 /* Reset the background color if necessary */
856 if ((background == 1 && outdepth == 1) ||
857 (background == 0 && outdepth != 1))
858 pixSetAll(pixd);
859
860 /* Blit the images to the dest, and save the boxa identifying
861 * the image regions that do not include the borders. */
862 nrows = numaGetCount(nainrow);
863 y = spacing;
864 boxa = boxaCreate(n);
865 for (i = 0, index = 0; i < nrows; i++) { /* over rows */
866 numaGetIValue(nainrow, i, &ninrow);
867 numaGetIValue(namaxh, i, &maxh);
868 x = spacing;
869 for (j = 0; j < ninrow; j++, index++) { /* over pix in row */
870 pix = pixaGetPix(pixan, index, L_CLONE);
871 if (index == 0) {
872 res = pixGetXRes(pix);
873 pixSetResolution(pixd, res, res);
874 }
875 pixGetDimensions(pix, &wt, &ht, NULL);
876 boxaAddBox(boxa, boxCreate(x + border, y + border,
877 wt - 2 * border, ht - 2 *border), L_INSERT);
878 pixRasterop(pixd, x, y, wt, ht, PIX_SRC, pix, 0, 0);
879 pixDestroy(&pix);
880 x += wt + spacing;
881 }
882 y += maxh + spacing;
883 }
884 if (boxaWriteMem(&data, &size, boxa) == 0)
885 pixSetText(pixd, (char *)data); /* data is ascii */
886 LEPT_FREE(data);
887 boxaDestroy(&boxa);
888
889 numaDestroy(&nainrow);
890 numaDestroy(&namaxh);
891 pixaDestroy(&pixan);
892 return pixd;
893}
894
895
929PIX *
931 l_int32 nx,
932 l_float32 scalefactor,
933 l_int32 spacing,
934 l_int32 border)
935{
936l_int32 i, j, index, n, x, y, nrows, wb, hb, w, h, maxd, maxh, bordval, res;
937size_t size;
938l_uint8 *data;
939BOX *box;
940BOXA *boxa;
941PIX *pix1, *pix2, *pix3, *pixd;
942PIXA *pixa1, *pixa2;
943
944 PROCNAME("pixaDisplayTiledInColumns");
945
946 if (!pixas)
947 return (PIX *)ERROR_PTR("pixas not defined", procName, NULL);
948 border = L_MAX(border, 0);
949 if (scalefactor <= 0.0) scalefactor = 1.0;
950 if ((n = pixaGetCount(pixas)) == 0)
951 return (PIX *)ERROR_PTR("no components", procName, NULL);
952
953 /* Convert to same depth, if necessary */
954 pixa1 = pixaConvertToSameDepth(pixas);
955 pixaGetDepthInfo(pixa1, &maxd, NULL);
956
957 /* Scale and optionally add border */
958 pixa2 = pixaCreate(n);
959 bordval = (maxd == 1) ? 1 : 0;
960 for (i = 0; i < n; i++) {
961 if ((pix1 = pixaGetPix(pixa1, i, L_CLONE)) == NULL)
962 continue;
963 if (scalefactor != 1.0)
964 pix2 = pixScale(pix1, scalefactor, scalefactor);
965 else
966 pix2 = pixClone(pix1);
967 if (border)
968 pix3 = pixAddBorder(pix2, border, bordval);
969 else
970 pix3 = pixClone(pix2);
971 if (i == 0) res = pixGetXRes(pix3);
972 pixaAddPix(pixa2, pix3, L_INSERT);
973 pixDestroy(&pix1);
974 pixDestroy(&pix2);
975 }
976 pixaDestroy(&pixa1);
977 if (pixaGetCount(pixa2) != n) {
978 n = pixaGetCount(pixa2);
979 L_WARNING("only got %d components\n", procName, n);
980 if (n == 0) {
981 pixaDestroy(&pixa2);
982 return (PIX *)ERROR_PTR("no components", procName, NULL);
983 }
984 }
985
986 /* Compute layout parameters and save as a boxa */
987 boxa = boxaCreate(n);
988 nrows = (n + nx - 1) / nx;
989 y = spacing;
990 for (i = 0, index = 0; i < nrows; i++) {
991 x = spacing;
992 maxh = 0;
993 for (j = 0; j < nx && index < n; j++) {
994 pixaGetPixDimensions(pixa2, index, &wb, &hb, NULL);
995 box = boxCreate(x, y, wb, hb);
996 boxaAddBox(boxa, box, L_INSERT);
997 maxh = L_MAX(maxh, hb + spacing);
998 x += wb + spacing;
999 index++;
1000 }
1001 y += maxh;
1002 }
1003 pixaSetBoxa(pixa2, boxa, L_INSERT);
1004
1005 /* Render the output pix */
1006 boxaGetExtent(boxa, &w, &h, NULL);
1007 pixd = pixaDisplay(pixa2, w + spacing, h + spacing);
1008 pixSetResolution(pixd, res, res);
1009
1010 /* Save the boxa in the text field of the output pix */
1011 if (boxaWriteMem(&data, &size, boxa) == 0)
1012 pixSetText(pixd, (char *)data); /* data is ascii */
1013 LEPT_FREE(data);
1014
1015 pixaDestroy(&pixa2);
1016 return pixd;
1017}
1018
1019
1044PIX *
1046 l_int32 outdepth,
1047 l_int32 tilewidth,
1048 l_int32 ncols,
1049 l_int32 background,
1050 l_int32 spacing,
1051 l_int32 border)
1052{
1053l_int32 x, y, w, h, wd, hd, d, res;
1054l_int32 i, n, nrows, maxht, ninrow, irow, bordval;
1055l_int32 *rowht;
1056l_float32 scalefact;
1057PIX *pix, *pixn, *pix1, *pixb, *pixd;
1058PIXA *pixan;
1059
1060 PROCNAME("pixaDisplayTiledAndScaled");
1061
1062 if (!pixa)
1063 return (PIX *)ERROR_PTR("pixa not defined", procName, NULL);
1064 if (outdepth != 1 && outdepth != 8 && outdepth != 32)
1065 return (PIX *)ERROR_PTR("outdepth not in {1, 8, 32}", procName, NULL);
1066 if (ncols <= 0)
1067 return (PIX *)ERROR_PTR("ncols must be > 0", procName, NULL);
1068 spacing = L_MAX(spacing, 0);
1069 if (border < 0 || border > tilewidth / 5)
1070 border = 0;
1071 if ((n = pixaGetCount(pixa)) == 0)
1072 return (PIX *)ERROR_PTR("no components", procName, NULL);
1073
1074 /* Normalize scale and depth for each pix; optionally add border */
1075 pixan = pixaCreate(n);
1076 bordval = (outdepth == 1) ? 1 : 0;
1077 for (i = 0; i < n; i++) {
1078 if ((pix = pixaGetPix(pixa, i, L_CLONE)) == NULL)
1079 continue;
1080
1081 pixGetDimensions(pix, &w, &h, &d);
1082 scalefact = (l_float32)(tilewidth - 2 * border) / (l_float32)w;
1083 if (d == 1 && outdepth > 1 && scalefact < 1.0)
1084 pix1 = pixScaleToGray(pix, scalefact);
1085 else
1086 pix1 = pixScale(pix, scalefact, scalefact);
1087
1088 if (outdepth == 1)
1089 pixn = pixConvertTo1(pix1, 128);
1090 else if (outdepth == 8)
1091 pixn = pixConvertTo8(pix1, FALSE);
1092 else /* outdepth == 32 */
1093 pixn = pixConvertTo32(pix1);
1094 pixDestroy(&pix1);
1095
1096 if (border)
1097 pixb = pixAddBorder(pixn, border, bordval);
1098 else
1099 pixb = pixClone(pixn);
1100
1101 pixaAddPix(pixan, pixb, L_INSERT);
1102 pixDestroy(&pix);
1103 pixDestroy(&pixn);
1104 }
1105 if ((n = pixaGetCount(pixan)) == 0) { /* should not have changed! */
1106 pixaDestroy(&pixan);
1107 return (PIX *)ERROR_PTR("no components", procName, NULL);
1108 }
1109
1110 /* Determine the size of each row and of pixd */
1111 wd = tilewidth * ncols + spacing * (ncols + 1);
1112 nrows = (n + ncols - 1) / ncols;
1113 if ((rowht = (l_int32 *)LEPT_CALLOC(nrows, sizeof(l_int32))) == NULL) {
1114 pixaDestroy(&pixan);
1115 return (PIX *)ERROR_PTR("rowht array not made", procName, NULL);
1116 }
1117 maxht = 0;
1118 ninrow = 0;
1119 irow = 0;
1120 for (i = 0; i < n; i++) {
1121 pix = pixaGetPix(pixan, i, L_CLONE);
1122 ninrow++;
1123 pixGetDimensions(pix, &w, &h, NULL);
1124 maxht = L_MAX(h, maxht);
1125 if (ninrow == ncols) {
1126 rowht[irow] = maxht;
1127 maxht = ninrow = 0; /* reset */
1128 irow++;
1129 }
1130 pixDestroy(&pix);
1131 }
1132 if (ninrow > 0) { /* last fencepost */
1133 rowht[irow] = maxht;
1134 irow++; /* total number of rows */
1135 }
1136 nrows = irow;
1137 hd = spacing * (nrows + 1);
1138 for (i = 0; i < nrows; i++)
1139 hd += rowht[i];
1140
1141 pixd = pixCreate(wd, hd, outdepth);
1142 if ((background == 1 && outdepth == 1) ||
1143 (background == 0 && outdepth != 1))
1144 pixSetAll(pixd);
1145
1146 /* Now blit images to pixd */
1147 x = y = spacing;
1148 irow = 0;
1149 for (i = 0; i < n; i++) {
1150 pix = pixaGetPix(pixan, i, L_CLONE);
1151 if (i == 0) {
1152 res = pixGetXRes(pix);
1153 pixSetResolution(pixd, res, res);
1154 }
1155 pixGetDimensions(pix, &w, &h, NULL);
1156 if (i && ((i % ncols) == 0)) { /* start new row */
1157 x = spacing;
1158 y += spacing + rowht[irow];
1159 irow++;
1160 }
1161 pixRasterop(pixd, x, y, w, h, PIX_SRC, pix, 0, 0);
1162 x += tilewidth + spacing;
1163 pixDestroy(&pix);
1164 }
1165
1166 pixaDestroy(&pixan);
1167 LEPT_FREE(rowht);
1168 return pixd;
1169}
1170
1171
1199PIX *
1201 l_int32 maxwidth,
1202 l_float32 scalefactor,
1203 l_int32 spacing,
1204 l_int32 border,
1205 l_int32 fontsize,
1206 l_uint32 textcolor)
1207{
1208char buf[128];
1209char *textstr;
1210l_int32 i, n, maxw;
1211L_BMF *bmf;
1212PIX *pix1, *pix2, *pix3, *pix4, *pixd;
1213PIXA *pixad;
1214
1215 PROCNAME("pixaDisplayTiledWithText");
1216
1217 if (!pixa)
1218 return (PIX *)ERROR_PTR("pixa not defined", procName, NULL);
1219 if ((n = pixaGetCount(pixa)) == 0)
1220 return (PIX *)ERROR_PTR("no components", procName, NULL);
1221 if (maxwidth <= 0)
1222 return (PIX *)ERROR_PTR("invalid maxwidth", procName, NULL);
1223 spacing = L_MAX(spacing, 0);
1224 border = L_MAX(border, 0);
1225 if (scalefactor <= 0.0) scalefactor = 1.0;
1226 if (fontsize < 4 || fontsize > 20 || (fontsize & 1)) {
1227 l_int32 fsize = L_MAX(L_MIN(fontsize, 20), 4);
1228 if (fsize & 1) fsize--;
1229 L_WARNING("changed fontsize from %d to %d\n", procName,
1230 fontsize, fsize);
1231 fontsize = fsize;
1232 }
1233
1234 /* Be sure the width can accommodate a single column of images */
1235 pixaSizeRange(pixa, NULL, NULL, &maxw, NULL);
1236 maxwidth = L_MAX(maxwidth, scalefactor * (maxw + 2 * spacing + 2 * border));
1237
1238 bmf = bmfCreate(NULL, fontsize);
1239 pixad = pixaCreate(n);
1240 for (i = 0; i < n; i++) {
1241 pix1 = pixaGetPix(pixa, i, L_CLONE);
1242 pix2 = pixConvertTo32(pix1);
1243 pix3 = pixAddBorderGeneral(pix2, spacing / 2, spacing / 2, spacing / 2,
1244 spacing / 2, 0xffffff00);
1245 textstr = pixGetText(pix1);
1246 if (textstr && strlen(textstr) > 0) {
1247 snprintf(buf, sizeof(buf), "%s", textstr);
1248 pix4 = pixAddSingleTextblock(pix3, bmf, buf, textcolor,
1249 L_ADD_BELOW, NULL);
1250 } else {
1251 pix4 = pixClone(pix3);
1252 }
1253 pixaAddPix(pixad, pix4, L_INSERT);
1254 pixDestroy(&pix1);
1255 pixDestroy(&pix2);
1256 pixDestroy(&pix3);
1257 }
1258 bmfDestroy(&bmf);
1259
1260 pixd = pixaDisplayTiledInRows(pixad, 32, maxwidth, scalefactor,
1261 0, spacing, border);
1262 pixaDestroy(&pixad);
1263 return pixd;
1264}
1265
1266
1295PIX *
1297 NUMA *na,
1298 l_int32 width,
1299 l_int32 spacing,
1300 l_int32 border,
1301 l_int32 fontsize,
1302 l_uint32 textcolor)
1303{
1304char buf[128];
1305char *textstr;
1306l_int32 i, n, x, y, w, h, yval, index;
1307l_float32 maxindex;
1308L_BMF *bmf;
1309BOX *box;
1310NUMA *nay; /* top of the next pix to add in that column */
1311PIX *pix1, *pix2, *pix3, *pix4, *pix5, *pixd;
1312PIXA *pixad;
1313
1314 PROCNAME("pixaDisplayTiledByIndex");
1315
1316 if (!pixa)
1317 return (PIX *)ERROR_PTR("pixa not defined", procName, NULL);
1318 if (!na)
1319 return (PIX *)ERROR_PTR("na not defined", procName, NULL);
1320 if ((n = pixaGetCount(pixa)) == 0)
1321 return (PIX *)ERROR_PTR("no pixa components", procName, NULL);
1322 if (n != numaGetCount(na))
1323 return (PIX *)ERROR_PTR("pixa and na counts differ", procName, NULL);
1324 if (width <= 0)
1325 return (PIX *)ERROR_PTR("invalid width", procName, NULL);
1326 if (width < 20)
1327 L_WARNING("very small width: %d\n", procName, width);
1328 spacing = L_MAX(spacing, 0);
1329 border = L_MAX(border, 0);
1330 if (fontsize < 4 || fontsize > 20 || (fontsize & 1)) {
1331 l_int32 fsize = L_MAX(L_MIN(fontsize, 20), 4);
1332 if (fsize & 1) fsize--;
1333 L_WARNING("changed fontsize from %d to %d\n", procName,
1334 fontsize, fsize);
1335 fontsize = fsize;
1336 }
1337
1338 /* The pix will be rendered in the order they occupy in pixa. */
1339 bmf = bmfCreate(NULL, fontsize);
1340 pixad = pixaCreate(n);
1341 numaGetMax(na, &maxindex, NULL);
1342 nay = numaMakeConstant(spacing, lept_roundftoi(maxindex) + 1);
1343 for (i = 0; i < n; i++) {
1344 numaGetIValue(na, i, &index);
1345 numaGetIValue(nay, index, &yval);
1346 pix1 = pixaGetPix(pixa, i, L_CLONE);
1347 pix2 = pixConvertTo32(pix1);
1348 pix3 = pixScaleToSize(pix2, width, 0);
1349 pix4 = pixAddBorderGeneral(pix3, border, border, border, border, 0);
1350 textstr = pixGetText(pix1);
1351 if (textstr && strlen(textstr) > 0) {
1352 snprintf(buf, sizeof(buf), "%s", textstr);
1353 pix5 = pixAddTextlines(pix4, bmf, textstr, textcolor, L_ADD_BELOW);
1354 } else {
1355 pix5 = pixClone(pix4);
1356 }
1357 pixaAddPix(pixad, pix5, L_INSERT);
1358 x = spacing + border + index * (2 * border + width + spacing);
1359 y = yval;
1360 pixGetDimensions(pix5, &w, &h, NULL);
1361 yval += h + spacing;
1362 numaSetValue(nay, index, yval);
1363 box = boxCreate(x, y, w, h);
1364 pixaAddBox(pixad, box, L_INSERT);
1365 pixDestroy(&pix1);
1366 pixDestroy(&pix2);
1367 pixDestroy(&pix3);
1368 pixDestroy(&pix4);
1369 }
1370 numaDestroy(&nay);
1371 bmfDestroy(&bmf);
1372
1373 pixd = pixaDisplay(pixad, 0, 0);
1374 pixaDestroy(&pixad);
1375 return pixd;
1376}
1377
1378
1379/*---------------------------------------------------------------------*
1380 * Pixa pair display *
1381 *---------------------------------------------------------------------*/
1419PIX *
1421 PIXA *pixas2,
1422 l_int32 nx,
1423 l_float32 scalefactor,
1424 l_int32 spacing1,
1425 l_int32 spacing2,
1426 l_int32 border1,
1427 l_int32 border2,
1428 l_int32 fontsize,
1429 l_int32 startindex,
1430 SARRAY *sa)
1431{
1432l_int32 i, n, w, maxd, maxd1, maxd2, res, text;
1433NUMA *na;
1434PIX *pixs1, *pixs2, *pix1, *pix2, *pix3, *pix4;
1435PIX *pix5, *pix6, *pix7, *pix8, *pix9;
1436PIXA *pixa1, *pixa2;
1437SARRAY *sa1;
1438
1439 PROCNAME("pixaDisplayPairTiledInColumns");
1440
1441 if (!pixas1)
1442 return (PIX *)ERROR_PTR("pixas1 not defined", procName, NULL);
1443 if (!pixas2)
1444 return (PIX *)ERROR_PTR("pixas2 not defined", procName, NULL);
1445 spacing1 = L_MAX(spacing1, 0);
1446 spacing2 = L_MAX(spacing2, 0);
1447 border1 = L_MAX(border1, 0);
1448 border2 = L_MAX(border2, 0);
1449 if (scalefactor <= 0.0) scalefactor = 1.0;
1450 if ((n = pixaGetCount(pixas1)) == 0)
1451 return (PIX *)ERROR_PTR("no components", procName, NULL);
1452 if (n != pixaGetCount(pixas2))
1453 return (PIX *)ERROR_PTR("pixa sizes differ", procName, NULL);
1454 text = (fontsize <= 0) ? 0 : 1;
1455 if (text && (fontsize < 4 || fontsize > 20 || (fontsize & 1))) {
1456 l_int32 fsize = L_MAX(L_MIN(fontsize, 20), 4);
1457 if (fsize & 1) fsize--;
1458 L_WARNING("changed fontsize from %d to %d\n", procName,
1459 fontsize, fsize);
1460 fontsize = fsize;
1461 }
1462
1463 /* Convert to same depth, if necessary */
1464 if (text) { /* adding color text; convert to 32 bpp */
1465 maxd = 32;
1466 } else {
1467 pixaGetRenderingDepth(pixas1, &maxd1);
1468 pixaGetRenderingDepth(pixas2, &maxd2);
1469 maxd = L_MAX(maxd1, maxd2);
1470 }
1471
1472 /* Optionally scale and add borders to each pair;
1473 then combine the pairs and add outer border. */
1474 pixa1 = pixaCreate(n);
1475 for (i = 0; i < n; i++) {
1476 pixs1 = pixaGetPix(pixas1, i, L_CLONE);
1477 pixs2 = pixaGetPix(pixas2, i, L_CLONE);
1478 if (!pixs1 || !pixs2) continue;
1479 if (maxd == 1) {
1480 pix1 = pixClone(pixs1);
1481 pix2 = pixClone(pixs2);
1482 } else if (maxd == 8) {
1483 pix1 = pixConvertTo8(pixs1, 0);
1484 pix2 = pixConvertTo8(pixs2, 0);
1485 } else { /* maxd == 32 */
1486 pix1 = pixConvertTo32(pixs1);
1487 pix2 = pixConvertTo32(pixs2);
1488 }
1489 pixDestroy(&pixs1);
1490 pixDestroy(&pixs2);
1491 if (scalefactor != 1.0) {
1492 pix3 = pixScale(pix1, scalefactor, scalefactor);
1493 pix4 = pixScale(pix2, scalefactor, scalefactor);
1494 } else {
1495 pix3 = pixClone(pix1);
1496 pix4 = pixClone(pix2);
1497 }
1498 pixDestroy(&pix1);
1499 pixDestroy(&pix2);
1500 if (border1) {
1501 pix5 = pixAddBlackOrWhiteBorder(pix3, border1, border1, border1,
1502 border1, L_GET_BLACK_VAL);
1503 pix6 = pixAddBlackOrWhiteBorder(pix4, border1, border1, border1,
1504 border1, L_GET_BLACK_VAL);
1505 } else {
1506 pix5 = pixClone(pix3);
1507 pix6 = pixClone(pix4);
1508 }
1509 if (i == 0) res = pixGetXRes(pix3);
1510 pixDestroy(&pix3);
1511 pixDestroy(&pix4);
1512 if (spacing1) { /* white border */
1513 pix7 = pixAddBlackOrWhiteBorder(pix5, spacing1 / 2, spacing1 / 2,
1514 spacing1 / 2, spacing1 / 2, L_GET_WHITE_VAL);
1515 pix8 = pixAddBlackOrWhiteBorder(pix6, spacing1 / 2, spacing1 / 2,
1516 spacing1 / 2, spacing1 / 2, L_GET_WHITE_VAL);
1517 } else {
1518 pix7 = pixClone(pix5);
1519 pix8 = pixClone(pix6);
1520 }
1521 pixDestroy(&pix5);
1522 pixDestroy(&pix6);
1523 pixa2 = pixaCreate(2);
1524 pixaAddPix(pixa2, pix7, L_INSERT);
1525 pixaAddPix(pixa2, pix8, L_INSERT);
1526 pix9 = pixaDisplayTiledInColumns(pixa2, 2, 1.0, 0, 0);
1527 pixaAddPix(pixa1, pix9, L_INSERT);
1528 pixaDestroy(&pixa2);
1529 }
1530
1531 if (!text) {
1532 pix1 = pixaDisplayTiledInColumns(pixa1, nx, 1.0, spacing2, border2);
1533 } else {
1534 if (sa) {
1535 pixaSetText(pixa1, NULL, sa);
1536 } else {
1537 n = pixaGetCount(pixa1);
1538 na = numaMakeSequence(startindex, 1, n);
1539 sa1 = numaConvertToSarray(na, 4, 0, 0, L_INTEGER_VALUE);
1540 pixaSetText(pixa1, NULL, sa1);
1541 numaDestroy(&na);
1542 sarrayDestroy(&sa1);
1543 }
1544 pixaSizeRange(pixa1, NULL, NULL, &w, NULL);
1545 pix1 = pixaDisplayTiledWithText(pixa1, w * (nx + 1), 1.0, spacing2,
1546 border2, fontsize, 0xff000000);
1547 }
1548 pixaDestroy(&pixa1);
1549 return pix1;
1550}
1551
1552
1553/*---------------------------------------------------------------------*
1554 * Pixaa Display *
1555 *---------------------------------------------------------------------*/
1571PIX *
1573 l_int32 w,
1574 l_int32 h)
1575{
1576l_int32 i, j, n, nbox, na, d, wmax, hmax, x, y, xb, yb, wb, hb;
1577BOXA *boxa1; /* top-level boxa */
1578BOXA *boxa;
1579PIX *pix1, *pixd;
1580PIXA *pixa;
1581
1582 PROCNAME("pixaaDisplay");
1583
1584 if (!paa)
1585 return (PIX *)ERROR_PTR("paa not defined", procName, NULL);
1586
1587 n = pixaaGetCount(paa, NULL);
1588 if (n == 0)
1589 return (PIX *)ERROR_PTR("no components", procName, NULL);
1590
1591 /* If w and h not input, determine the minimum size required
1592 * to contain the origin and all c.c. */
1593 boxa1 = pixaaGetBoxa(paa, L_CLONE);
1594 nbox = boxaGetCount(boxa1);
1595 if (w == 0 || h == 0) {
1596 if (nbox == n) {
1597 boxaGetExtent(boxa1, &w, &h, NULL);
1598 } else { /* have to use the lower-level boxa for each pixa */
1599 wmax = hmax = 0;
1600 for (i = 0; i < n; i++) {
1601 pixa = pixaaGetPixa(paa, i, L_CLONE);
1602 boxa = pixaGetBoxa(pixa, L_CLONE);
1603 boxaGetExtent(boxa, &w, &h, NULL);
1604 wmax = L_MAX(wmax, w);
1605 hmax = L_MAX(hmax, h);
1606 pixaDestroy(&pixa);
1607 boxaDestroy(&boxa);
1608 }
1609 w = wmax;
1610 h = hmax;
1611 }
1612 }
1613
1614 /* Get depth from first pix */
1615 pixa = pixaaGetPixa(paa, 0, L_CLONE);
1616 pix1 = pixaGetPix(pixa, 0, L_CLONE);
1617 d = pixGetDepth(pix1);
1618 pixaDestroy(&pixa);
1619 pixDestroy(&pix1);
1620
1621 if ((pixd = pixCreate(w, h, d)) == NULL) {
1622 boxaDestroy(&boxa1);
1623 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
1624 }
1625
1626 x = y = 0;
1627 for (i = 0; i < n; i++) {
1628 pixa = pixaaGetPixa(paa, i, L_CLONE);
1629 if (nbox == n)
1630 boxaGetBoxGeometry(boxa1, i, &x, &y, NULL, NULL);
1631 na = pixaGetCount(pixa);
1632 for (j = 0; j < na; j++) {
1633 pixaGetBoxGeometry(pixa, j, &xb, &yb, &wb, &hb);
1634 pix1 = pixaGetPix(pixa, j, L_CLONE);
1635 pixRasterop(pixd, x + xb, y + yb, wb, hb, PIX_PAINT, pix1, 0, 0);
1636 pixDestroy(&pix1);
1637 }
1638 pixaDestroy(&pixa);
1639 }
1640 boxaDestroy(&boxa1);
1641
1642 return pixd;
1643}
1644
1645
1674PIX *
1676 l_int32 maxnx,
1677 l_float32 scalefactor,
1678 l_int32 hspacing,
1679 l_int32 vspacing,
1680 l_int32 border)
1681{
1682l_int32 i, n, vs;
1683PIX *pix1, *pix2;
1684PIXA *pixa1, *pixa2;
1685
1686 PROCNAME("pixaaDisplayByPixa");
1687
1688 if (!paa)
1689 return (PIX *)ERROR_PTR("paa not defined", procName, NULL);
1690 if (scalefactor <= 0.0) scalefactor = 1.0;
1691 if (hspacing < 0) hspacing = 0;
1692 if (vspacing < 0) vspacing = 0;
1693 if (border < 0) border = 0;
1694
1695 if ((n = pixaaGetCount(paa, NULL)) == 0)
1696 return (PIX *)ERROR_PTR("no components", procName, NULL);
1697
1698 /* Vertical spacing of amount %hspacing is also added at this step */
1699 pixa2 = pixaCreate(0);
1700 for (i = 0; i < n; i++) {
1701 pixa1 = pixaaGetPixa(paa, i, L_CLONE);
1702 pix1 = pixaDisplayTiledInColumns(pixa1, maxnx, scalefactor,
1703 hspacing, border);
1704 pixaAddPix(pixa2, pix1, L_INSERT);
1705 pixaDestroy(&pixa1);
1706 }
1707
1708 vs = vspacing - 2 * hspacing;
1709 pix2 = pixaDisplayTiledInColumns(pixa2, 1, scalefactor, vs, 0);
1710 pixaDestroy(&pixa2);
1711 return pix2;
1712}
1713
1714
1737PIXA *
1739 l_int32 outdepth,
1740 l_int32 tilewidth,
1741 l_int32 ncols,
1742 l_int32 background,
1743 l_int32 spacing,
1744 l_int32 border)
1745{
1746l_int32 i, n;
1747PIX *pix;
1748PIXA *pixa, *pixad;
1749
1750 PROCNAME("pixaaDisplayTiledAndScaled");
1751
1752 if (!paa)
1753 return (PIXA *)ERROR_PTR("paa not defined", procName, NULL);
1754 if (outdepth != 1 && outdepth != 8 && outdepth != 32)
1755 return (PIXA *)ERROR_PTR("outdepth not in {1, 8, 32}", procName, NULL);
1756 if (ncols <= 0)
1757 return (PIXA *)ERROR_PTR("ncols must be > 0", procName, NULL);
1758 if (border < 0 || border > tilewidth / 5)
1759 border = 0;
1760
1761 if ((n = pixaaGetCount(paa, NULL)) == 0)
1762 return (PIXA *)ERROR_PTR("no components", procName, NULL);
1763
1764 pixad = pixaCreate(n);
1765 for (i = 0; i < n; i++) {
1766 pixa = pixaaGetPixa(paa, i, L_CLONE);
1767 pix = pixaDisplayTiledAndScaled(pixa, outdepth, tilewidth, ncols,
1768 background, spacing, border);
1769 pixaAddPix(pixad, pix, L_INSERT);
1770 pixaDestroy(&pixa);
1771 }
1772
1773 return pixad;
1774}
1775
1776
1777/*---------------------------------------------------------------------*
1778 * Conversion of all pix to specified type (e.g., depth) *
1779 *---------------------------------------------------------------------*/
1787PIXA *
1789 l_int32 thresh)
1790{
1791l_int32 i, n;
1792BOXA *boxa;
1793PIX *pix1, *pix2;
1794PIXA *pixad;
1795
1796 PROCNAME("pixaConvertTo1");
1797
1798 if (!pixas)
1799 return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1800
1801 n = pixaGetCount(pixas);
1802 pixad = pixaCreate(n);
1803 for (i = 0; i < n; i++) {
1804 pix1 = pixaGetPix(pixas, i, L_CLONE);
1805 pix2 = pixConvertTo1(pix1, thresh);
1806 pixaAddPix(pixad, pix2, L_INSERT);
1807 pixDestroy(&pix1);
1808 }
1809
1810 boxa = pixaGetBoxa(pixas, L_COPY);
1811 pixaSetBoxa(pixad, boxa, L_INSERT);
1812 return pixad;
1813}
1814
1815
1828PIXA *
1830 l_int32 cmapflag)
1831{
1832l_int32 i, n;
1833BOXA *boxa;
1834PIX *pix1, *pix2;
1835PIXA *pixad;
1836
1837 PROCNAME("pixaConvertTo8");
1838
1839 if (!pixas)
1840 return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1841
1842 n = pixaGetCount(pixas);
1843 pixad = pixaCreate(n);
1844 for (i = 0; i < n; i++) {
1845 pix1 = pixaGetPix(pixas, i, L_CLONE);
1846 pix2 = pixConvertTo8(pix1, cmapflag);
1847 pixaAddPix(pixad, pix2, L_INSERT);
1848 pixDestroy(&pix1);
1849 }
1850
1851 boxa = pixaGetBoxa(pixas, L_COPY);
1852 pixaSetBoxa(pixad, boxa, L_INSERT);
1853 return pixad;
1854}
1855
1856
1869PIXA *
1871 l_int32 dither)
1872{
1873l_int32 i, n;
1874BOXA *boxa;
1875PIX *pix1, *pix2;
1876PIXA *pixad;
1877
1878 PROCNAME("pixaConvertTo8Colormap");
1879
1880 if (!pixas)
1881 return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1882
1883 n = pixaGetCount(pixas);
1884 pixad = pixaCreate(n);
1885 for (i = 0; i < n; i++) {
1886 pix1 = pixaGetPix(pixas, i, L_CLONE);
1887 pix2 = pixConvertTo8Colormap(pix1, dither);
1888 pixaAddPix(pixad, pix2, L_INSERT);
1889 pixDestroy(&pix1);
1890 }
1891
1892 boxa = pixaGetBoxa(pixas, L_COPY);
1893 pixaSetBoxa(pixad, boxa, L_INSERT);
1894 return pixad;
1895}
1896
1897
1911PIXA *
1913{
1914l_int32 i, n;
1915BOXA *boxa;
1916PIX *pix1, *pix2;
1917PIXA *pixad;
1918
1919 PROCNAME("pixaConvertTo32");
1920
1921 if (!pixas)
1922 return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1923
1924 n = pixaGetCount(pixas);
1925 pixad = pixaCreate(n);
1926 for (i = 0; i < n; i++) {
1927 pix1 = pixaGetPix(pixas, i, L_CLONE);
1928 pix2 = pixConvertTo32(pix1);
1929 pixaAddPix(pixad, pix2, L_INSERT);
1930 pixDestroy(&pix1);
1931 }
1932
1933 boxa = pixaGetBoxa(pixas, L_COPY);
1934 pixaSetBoxa(pixad, boxa, L_INSERT);
1935 return pixad;
1936}
1937
1938
1939/*---------------------------------------------------------------------*
1940 * Pixa constrained selection *
1941 *---------------------------------------------------------------------*/
1964PIXA *
1966 l_int32 first,
1967 l_int32 last,
1968 l_int32 nmax,
1969 l_int32 use_pairs,
1970 l_int32 copyflag)
1971{
1972l_int32 i, n, nselect, index;
1973NUMA *na;
1974PIX *pix1;
1975PIXA *pixad;
1976
1977 PROCNAME("pixaConstrainedSelect");
1978
1979 if (!pixas)
1980 return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1981 n = pixaGetCount(pixas);
1982 first = L_MAX(0, first);
1983 last = (last < 0) ? n - 1 : L_MIN(n - 1, last);
1984 if (last < first)
1985 return (PIXA *)ERROR_PTR("last < first!", procName, NULL);
1986 if (nmax < 1)
1987 return (PIXA *)ERROR_PTR("nmax < 1!", procName, NULL);
1988
1989 na = genConstrainedNumaInRange(first, last, nmax, use_pairs);
1990 nselect = numaGetCount(na);
1991 pixad = pixaCreate(nselect);
1992 for (i = 0; i < nselect; i++) {
1993 numaGetIValue(na, i, &index);
1994 pix1 = pixaGetPix(pixas, index, copyflag);
1995 pixaAddPix(pixad, pix1, L_INSERT);
1996 }
1997 numaDestroy(&na);
1998 return pixad;
1999}
2000
2001
2032l_ok
2034 l_int32 first,
2035 l_int32 last,
2036 l_int32 res,
2037 l_float32 scalefactor,
2038 l_int32 type,
2039 l_int32 quality,
2040 l_uint32 color,
2041 l_int32 fontsize,
2042 const char *fileout)
2043{
2044l_int32 n;
2045L_BMF *bmf;
2046NUMA *na;
2047PIXA *pixa1, *pixa2;
2048
2049 PROCNAME("pixaSelectToPdf");
2050
2051 if (!pixas)
2052 return ERROR_INT("pixas not defined", procName, 1);
2053 if (type < 0 || type > L_FLATE_ENCODE) {
2054 L_WARNING("invalid compression type; using default\n", procName);
2055 type = 0;
2056 }
2057 if (!fileout)
2058 return ERROR_INT("fileout not defined", procName, 1);
2059
2060 /* Select from given range */
2061 n = pixaGetCount(pixas);
2062 first = L_MAX(0, first);
2063 last = (last < 0) ? n - 1 : L_MIN(n - 1, last);
2064 if (first > last) {
2065 L_ERROR("first = %d > last = %d\n", procName, first, last);
2066 return 1;
2067 }
2068 pixa1 = pixaSelectRange(pixas, first, last, L_CLONE);
2069
2070 /* Optionally add index numbers */
2071 bmf = (fontsize <= 0) ? NULL : bmfCreate(NULL, fontsize);
2072 if (bmf) {
2073 na = numaMakeSequence(first, 1.0, last - first + 1);
2074 pixa2 = pixaAddTextNumber(pixa1, bmf, na, color, L_ADD_LEFT);
2075 numaDestroy(&na);
2076 } else {
2077 pixa2 = pixaCopy(pixa1, L_CLONE);
2078 }
2079 pixaDestroy(&pixa1);
2080 bmfDestroy(&bmf);
2081
2082 pixaConvertToPdf(pixa2, res, scalefactor, type, quality, NULL, fileout);
2083 pixaDestroy(&pixa2);
2084 return 0;
2085}
2086
2087
2088/*---------------------------------------------------------------------*
2089 * Generate pixa from tiled images *
2090 *---------------------------------------------------------------------*/
2111PIXA *
2113 l_int32 w,
2114 l_int32 h,
2115 l_int32 nsamp)
2116{
2117char buf[8];
2118l_int32 ntiles, i;
2119PIX *pix1;
2120PIXA *pixad, *pixa1;
2121
2122 PROCNAME("pixaMakeFromTiledPixa");
2123
2124 if (!pixas)
2125 return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
2126 if (nsamp > 1000)
2127 return (PIXA *)ERROR_PTR("nsamp too large; typ. 100", procName, NULL);
2128
2129 if (w <= 0) w = 20;
2130 if (h <= 0) h = 30;
2131 if (nsamp <= 0) nsamp = 100;
2132
2133 /* pixas has 10 pix of mosaic'd digits. Each of these images
2134 * must be extracted into a pixa of templates, where each template
2135 * is labeled with the digit value, and then selectively
2136 * concatenated into an output pixa. */
2137 pixad = pixaCreate(10 * nsamp);
2138 for (i = 0; i < 10; i++) {
2139 pix1 = pixaGetPix(pixas, i, L_CLONE);
2140 pixGetTileCount(pix1, &ntiles);
2141 if (nsamp > ntiles)
2142 L_WARNING("requested %d; only %d tiles\n", procName, nsamp, ntiles);
2143 pixa1 = pixaMakeFromTiledPix(pix1, w, h, 0, nsamp, NULL);
2144 snprintf(buf, sizeof(buf), "%d", i);
2145 pixaSetText(pixa1, buf, NULL);
2146 pixaJoin(pixad, pixa1, 0, -1);
2147 pixaDestroy(&pixa1);
2148 pixDestroy(&pix1);
2149 }
2150 return pixad;
2151}
2152
2153
2191PIXA *
2193 l_int32 w,
2194 l_int32 h,
2195 l_int32 start,
2196 l_int32 num,
2197 BOXA *boxa)
2198{
2199l_int32 i, j, k, ws, hs, d, nx, ny, n, n_isvalid, ntiles, nmax;
2200PIX *pix1;
2201PIXA *pixa1;
2202PIXCMAP *cmap;
2203
2204 PROCNAME("pixaMakeFromTiledPix");
2205
2206 if (!pixs)
2207 return (PIXA *)ERROR_PTR("pixs not defined", procName, NULL);
2208 if (!boxa && (w <= 0 || h <= 0))
2209 return (PIXA *)ERROR_PTR("w and h must be > 0", procName, NULL);
2210
2211 if (boxa) /* general case */
2212 return pixaCreateFromBoxa(pixs, boxa, start, num, NULL);
2213
2214 /* All tiles are the same size */
2215 pixGetDimensions(pixs, &ws, &hs, &d);
2216 nx = ws / w;
2217 ny = hs / h;
2218 if (nx < 1 || ny < 1)
2219 return (PIXA *)ERROR_PTR("invalid dimensions", procName, NULL);
2220 if (nx * w != ws || ny * h != hs)
2221 L_WARNING("some tiles will be clipped\n", procName);
2222
2223 /* Check the text field of the pix. It may tell how many
2224 * tiles hold valid data. If a valid value is not found,
2225 * assume all (nx * ny) tiles are valid. */
2226 pixGetTileCount(pixs, &n);
2227 n_isvalid = (n <= nx * ny && n > nx * (ny - 1)) ? TRUE : FALSE;
2228 ntiles = (n_isvalid) ? n : nx * ny;
2229 nmax = ntiles - start; /* max available from start */
2230 num = (num == 0) ? nmax : L_MIN(num, nmax);
2231
2232 /* Extract the tiles */
2233 if ((pixa1 = pixaCreate(num)) == NULL) {
2234 return (PIXA *)ERROR_PTR("pixa1 not made", procName, NULL);
2235 }
2236 cmap = pixGetColormap(pixs);
2237 for (i = 0, k = 0; i < ny; i++) {
2238 for (j = 0; j < nx; j++, k++) {
2239 if (k < start) continue;
2240 if (k >= start + num) break;
2241 pix1 = pixCreate(w, h, d);
2242 if (cmap) pixSetColormap(pix1, pixcmapCopy(cmap));
2243 pixRasterop(pix1, 0, 0, w, h, PIX_SRC, pixs, j * w, i * h);
2244 pixaAddPix(pixa1, pix1, L_INSERT);
2245 }
2246 }
2247 return pixa1;
2248}
2249
2250
2266l_ok
2268 l_int32 *pn)
2269{
2270char *text;
2271l_int32 n;
2272
2273 PROCNAME("pixGetTileCount");
2274
2275 if (!pn)
2276 return ERROR_INT("&n not defined", procName, 1);
2277 *pn = 0;
2278 if (!pix)
2279 return ERROR_INT("pix not defined", procName, 1);
2280
2281 text = pixGetText(pix);
2282 if (text && strlen(text) > 4) {
2283 if (sscanf(text, "n = %d", &n) == 1)
2284 *pn = n;
2285 }
2286 return 0;
2287}
2288
2289
2290/*---------------------------------------------------------------------*
2291 * Pixa display into multiple tiles *
2292 *---------------------------------------------------------------------*/
2314PIXA *
2316 l_int32 nx,
2317 l_int32 ny,
2318 l_int32 maxw,
2319 l_int32 maxh,
2320 l_float32 scalefactor,
2321 l_int32 spacing,
2322 l_int32 border)
2323{
2324l_int32 n, i, j, ntile, nout, index;
2325PIX *pix1, *pix2;
2326PIXA *pixa1, *pixa2, *pixad;
2327
2328 PROCNAME("pixaDisplayMultiTiled");
2329
2330 if (!pixas)
2331 return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
2332 if (nx < 1 || ny < 1 || nx > 50 || ny > 50)
2333 return (PIXA *)ERROR_PTR("invalid tiling factor(s)", procName, NULL);
2334 if ((n = pixaGetCount(pixas)) == 0)
2335 return (PIXA *)ERROR_PTR("pixas is empty", procName, NULL);
2336
2337 /* Filter out large ones if requested */
2338 if (maxw == 0 && maxh == 0) {
2339 pixa1 = pixaCopy(pixas, L_CLONE);
2340 } else {
2341 maxw = (maxw == 0) ? 1000000 : maxw;
2342 maxh = (maxh == 0) ? 1000000 : maxh;
2343 pixa1 = pixaSelectBySize(pixas, maxw, maxh, L_SELECT_IF_BOTH,
2344 L_SELECT_IF_LTE, NULL);
2345 n = pixaGetCount(pixa1);
2346 }
2347
2348 ntile = nx * ny;
2349 nout = L_MAX(1, (n + ntile - 1) / ntile);
2350 pixad = pixaCreate(nout);
2351 for (i = 0, index = 0; i < nout; i++) { /* over tiles */
2352 pixa2 = pixaCreate(ntile);
2353 for (j = 0; j < ntile && index < n; j++, index++) {
2354 pix1 = pixaGetPix(pixa1, index, L_COPY);
2355 pixaAddPix(pixa2, pix1, L_INSERT);
2356 }
2357 pix2 = pixaDisplayTiledInColumns(pixa2, nx, scalefactor, spacing,
2358 border);
2359 pixaAddPix(pixad, pix2, L_INSERT);
2360 pixaDestroy(&pixa2);
2361 }
2362 pixaDestroy(&pixa1);
2363
2364 return pixad;
2365}
2366
2367
2368/*---------------------------------------------------------------------*
2369 * Split pixa into files *
2370 *---------------------------------------------------------------------*/
2393l_ok
2395 l_int32 nsplit,
2396 l_float32 scale,
2397 l_int32 outwidth,
2398 l_int32 write_pixa,
2399 l_int32 write_pix,
2400 l_int32 write_pdf)
2401{
2402char buf[64];
2403l_int32 i, j, index, n, nt;
2404PIX *pix1, *pix2;
2405PIXA *pixa1;
2406
2407 PROCNAME("pixaSplitIntoFiles");
2408
2409 if (!pixas)
2410 return ERROR_INT("pixas not defined", procName, 1);
2411 if (nsplit <= 1)
2412 return ERROR_INT("nsplit must be >= 2", procName, 1);
2413 if ((nt = pixaGetCount(pixas)) == 0)
2414 return ERROR_INT("pixas is empty", procName, 1);
2415 if (!write_pixa && !write_pix && !write_pdf)
2416 return ERROR_INT("no output is requested", procName, 1);
2417
2418 lept_mkdir("lept/split");
2419 n = (nt + nsplit - 1) / nsplit;
2420 lept_stderr("nt = %d, n = %d, nsplit = %d\n", nt, n, nsplit);
2421 for (i = 0, index = 0; i < nsplit; i++) {
2422 pixa1 = pixaCreate(n);
2423 for (j = 0; j < n && index < nt; j++, index++) {
2424 pix1 = pixaGetPix(pixas, index, L_CLONE);
2425 pix2 = pixScale(pix1, scale, scale);
2426 pixaAddPix(pixa1, pix2, L_INSERT);
2427 pixDestroy(&pix1);
2428 }
2429 if (write_pixa) {
2430 snprintf(buf, sizeof(buf), "/tmp/lept/split/split%d.pa", i + 1);
2431 pixaWriteDebug(buf, pixa1);
2432 }
2433 if (write_pix) {
2434 snprintf(buf, sizeof(buf), "/tmp/lept/split/split%d.tif", i + 1);
2435 pix1 = pixaDisplayTiledInRows(pixa1, 1, outwidth, 1.0, 0, 20, 2);
2436 pixWriteDebug(buf, pix1, IFF_TIFF_G4);
2437 pixDestroy(&pix1);
2438 }
2439 if (write_pdf) {
2440 snprintf(buf, sizeof(buf), "/tmp/lept/split/split%d.pdf", i + 1);
2441 pixaConvertToPdf(pixa1, 0, 1.0, L_G4_ENCODE, 0, buf, buf);
2442 }
2443 pixaDestroy(&pixa1);
2444 }
2445
2446 return 0;
2447}
2448
2449
2450/*---------------------------------------------------------------------*
2451 * Tile N-Up *
2452 *---------------------------------------------------------------------*/
2482l_ok
2483convertToNUpFiles(const char *dir,
2484 const char *substr,
2485 l_int32 nx,
2486 l_int32 ny,
2487 l_int32 tw,
2488 l_int32 spacing,
2489 l_int32 border,
2490 l_int32 fontsize,
2491 const char *outdir)
2492{
2493l_int32 d, format;
2494char rootpath[256];
2495PIXA *pixa;
2496
2497 PROCNAME("convertToNUpFiles");
2498
2499 if (!dir)
2500 return ERROR_INT("dir not defined", procName, 1);
2501 if (nx < 1 || ny < 1 || nx > 50 || ny > 50)
2502 return ERROR_INT("invalid tiling N-factor", procName, 1);
2503 if (fontsize < 0 || fontsize > 20 || fontsize & 1 || fontsize == 2)
2504 return ERROR_INT("invalid fontsize", procName, 1);
2505 if (!outdir)
2506 return ERROR_INT("outdir not defined", procName, 1);
2507
2508 pixa = convertToNUpPixa(dir, substr, nx, ny, tw, spacing, border,
2509 fontsize);
2510 if (!pixa)
2511 return ERROR_INT("pixa not made", procName, 1);
2512
2513 lept_rmdir(outdir);
2514 lept_mkdir(outdir);
2515 pixaGetRenderingDepth(pixa, &d);
2516 format = (d == 1) ? IFF_TIFF_G4 : IFF_JFIF_JPEG;
2517 makeTempDirname(rootpath, 256, outdir);
2518 modifyTrailingSlash(rootpath, 256, L_ADD_TRAIL_SLASH);
2519 pixaWriteFiles(rootpath, pixa, format);
2520 pixaDestroy(&pixa);
2521 return 0;
2522}
2523
2524
2544PIXA *
2545convertToNUpPixa(const char *dir,
2546 const char *substr,
2547 l_int32 nx,
2548 l_int32 ny,
2549 l_int32 tw,
2550 l_int32 spacing,
2551 l_int32 border,
2552 l_int32 fontsize)
2553{
2554l_int32 i, n;
2555char *fname, *tail;
2556PIXA *pixa1, *pixa2;
2557SARRAY *sa1, *sa2;
2558
2559 PROCNAME("convertToNUpPixa");
2560
2561 if (!dir)
2562 return (PIXA *)ERROR_PTR("dir not defined", procName, NULL);
2563 if (nx < 1 || ny < 1 || nx > 50 || ny > 50)
2564 return (PIXA *)ERROR_PTR("invalid tiling N-factor", procName, NULL);
2565 if (tw < 20)
2566 return (PIXA *)ERROR_PTR("tw must be >= 20", procName, NULL);
2567 if (fontsize < 0 || fontsize > 20 || fontsize & 1 || fontsize == 2)
2568 return (PIXA *)ERROR_PTR("invalid fontsize", procName, NULL);
2569
2570 sa1 = getSortedPathnamesInDirectory(dir, substr, 0, 0);
2571 pixa1 = pixaReadFilesSA(sa1);
2572 n = sarrayGetCount(sa1);
2573 sa2 = sarrayCreate(n);
2574 for (i = 0; i < n; i++) {
2575 fname = sarrayGetString(sa1, i, L_NOCOPY);
2576 splitPathAtDirectory(fname, NULL, &tail);
2577 sarrayAddString(sa2, tail, L_INSERT);
2578 }
2579 sarrayDestroy(&sa1);
2580 pixa2 = pixaConvertToNUpPixa(pixa1, sa2, nx, ny, tw, spacing,
2581 border, fontsize);
2582 pixaDestroy(&pixa1);
2583 sarrayDestroy(&sa2);
2584 return pixa2;
2585}
2586
2587
2610PIXA *
2612 SARRAY *sa,
2613 l_int32 nx,
2614 l_int32 ny,
2615 l_int32 tw,
2616 l_int32 spacing,
2617 l_int32 border,
2618 l_int32 fontsize)
2619{
2620l_int32 i, j, k, nt, n2, nout, d;
2621char *str;
2622L_BMF *bmf;
2623PIX *pix1, *pix2, *pix3, *pix4;
2624PIXA *pixa1, *pixad;
2625
2626 PROCNAME("pixaConvertToNUpPixa");
2627
2628 if (!pixas)
2629 return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
2630 if (nx < 1 || ny < 1 || nx > 50 || ny > 50)
2631 return (PIXA *)ERROR_PTR("invalid tiling N-factor", procName, NULL);
2632 if (tw < 20)
2633 return (PIXA *)ERROR_PTR("tw must be >= 20", procName, NULL);
2634 if (fontsize < 0 || fontsize > 20 || fontsize & 1 || fontsize == 2)
2635 return (PIXA *)ERROR_PTR("invalid fontsize", procName, NULL);
2636
2637 nt = pixaGetCount(pixas);
2638 if (sa && (sarrayGetCount(sa) != nt)) {
2639 L_WARNING("pixa size %d not equal to sarray size %d\n", procName,
2640 nt, sarrayGetCount(sa));
2641 }
2642
2643 n2 = nx * ny;
2644 nout = (nt + n2 - 1) / n2;
2645 pixad = pixaCreate(nout);
2646 bmf = (fontsize == 0) ? NULL : bmfCreate(NULL, fontsize);
2647 for (i = 0, j = 0; i < nout; i++) {
2648 pixa1 = pixaCreate(n2);
2649 for (k = 0; k < n2 && j < nt; j++, k++) {
2650 pix1 = pixaGetPix(pixas, j, L_CLONE);
2651 pix2 = pixScaleToSize(pix1, tw, 0); /* all images have width tw */
2652 if (bmf && sa) {
2653 str = sarrayGetString(sa, j, L_NOCOPY);
2654 pix3 = pixAddTextlines(pix2, bmf, str, 0xff000000,
2655 L_ADD_BELOW);
2656 } else {
2657 pix3 = pixClone(pix2);
2658 }
2659 pixaAddPix(pixa1, pix3, L_INSERT);
2660 pixDestroy(&pix1);
2661 pixDestroy(&pix2);
2662 }
2663 if (pixaGetCount(pixa1) == 0) { /* probably won't happen */
2664 pixaDestroy(&pixa1);
2665 continue;
2666 }
2667
2668 /* Add 2 * border to image width to prevent scaling */
2669 pixaGetRenderingDepth(pixa1, &d);
2670 pix4 = pixaDisplayTiledAndScaled(pixa1, d, tw + 2 * border, nx, 0,
2671 spacing, border);
2672 pixaAddPix(pixad, pix4, L_INSERT);
2673 pixaDestroy(&pixa1);
2674 }
2675
2676 bmfDestroy(&bmf);
2677 return pixad;
2678}
2679
2680
2681/*---------------------------------------------------------------------*
2682 * Render two pixa side-by-side for comparison *
2683 *---------------------------------------------------------------------*/
2723l_ok
2725 PIXA *pixa2,
2726 l_int32 nx,
2727 l_int32 ny,
2728 l_int32 tw,
2729 l_int32 spacing,
2730 l_int32 border,
2731 l_int32 fontsize,
2732 const char *fileout)
2733{
2734l_int32 n1, n2, npairs;
2735PIXA *pixa3, *pixa4, *pixa5;
2736SARRAY *sa;
2737
2738 PROCNAME("pixaCompareInPdf");
2739
2740 if (!pixa1 || !pixa2)
2741 return ERROR_INT("pixa1 and pixa2 not both defined", procName, 1);
2742 if (nx < 1 || ny < 1 || nx > 20 || ny > 20)
2743 return ERROR_INT("invalid tiling factors", procName, 1);
2744 if (tw < 20)
2745 return ERROR_INT("invalid tw; tw must be >= 20", procName, 1);
2746 if (fontsize < 0 || fontsize > 20 || fontsize & 1 || fontsize == 2)
2747 return ERROR_INT("invalid fontsize", procName, 1);
2748 if (!fileout)
2749 return ERROR_INT("fileout not defined", procName, 1);
2750 n1 = pixaGetCount(pixa1);
2751 n2 = pixaGetCount(pixa2);
2752 if (n1 == 0 || n2 == 0)
2753 return ERROR_INT("at least one pixa is empty", procName, 1);
2754 if (n1 != n2)
2755 L_WARNING("sizes (%d, %d) differ; using the minimum in interleave\n",
2756 procName, n1, n2);
2757
2758 /* Interleave the input pixa */
2759 if ((pixa3 = pixaInterleave(pixa1, pixa2, L_CLONE)) == NULL)
2760 return ERROR_INT("pixa3 not made", procName, 1);
2761
2762 /* Scale the images if necessary and pair them up side/by/side */
2763 pixa4 = pixaConvertToNUpPixa(pixa3, NULL, 2, 1, tw, spacing, border, 0);
2764 pixaDestroy(&pixa3);
2765
2766 /* Label the pairs and mosaic into pages without further scaling */
2767 npairs = pixaGetCount(pixa4);
2768 sa = (fontsize > 0) ? sarrayGenerateIntegers(npairs) : NULL;
2769 pixa5 = pixaConvertToNUpPixa(pixa4, sa, nx, ny,
2770 2 * tw + 4 * border + spacing,
2771 spacing, border, fontsize);
2772 pixaDestroy(&pixa4);
2773 sarrayDestroy(&sa);
2774
2775 /* Output as pdf without scaling */
2776 pixaConvertToPdf(pixa5, 0, 1.0, 0, 0, NULL, fileout);
2777 pixaDestroy(&pixa5);
2778 return 0;
2779}
2780
2781
@ L_INTEGER_VALUE
Definition: array.h:164
void bmfDestroy(L_BMF **pbmf)
bmfDestroy()
Definition: bmf.c:169
L_BMF * bmfCreate(const char *dir, l_int32 fontsize)
bmfCreate()
Definition: bmf.c:117
l_ok boxaWriteMem(l_uint8 **pdata, size_t *psize, BOXA *boxa)
boxaWriteMem()
Definition: boxbasic.c:2371
BOX * boxCreate(l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxCreate()
Definition: boxbasic.c:172
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
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 boxaGetExtent(BOXA *boxa, l_int32 *pw, l_int32 *ph, BOX **pbox)
boxaGetExtent()
Definition: boxfunc4.c:953
PIXCMAP * pixcmapCreateRandom(l_int32 depth, l_int32 hasblack, l_int32 haswhite)
pixcmapCreateRandom()
Definition: colormap.c:172
PIXCMAP * pixcmapCopy(const PIXCMAP *cmaps)
pixcmapCopy()
Definition: colormap.c:248
@ L_FLATE_ENCODE
Definition: imageio.h:161
@ L_G4_ENCODE
Definition: imageio.h:160
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:478
SARRAY * numaConvertToSarray(NUMA *na, l_int32 size1, l_int32 size2, l_int32 addzeros, l_int32 type)
numaConvertToSarray()
Definition: numabasic.c:1054
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:366
l_ok numaSetValue(NUMA *na, l_int32 index, l_float32 val)
numaSetValue()
Definition: numabasic.c:786
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 * numaMakeSequence(l_float32 startval, l_float32 increment, l_int32 size)
numaMakeSequence()
Definition: numafunc1.c:821
l_ok numaGetMax(NUMA *na, l_float32 *pmaxval, l_int32 *pimaxloc)
numaGetMax()
Definition: numafunc1.c:496
NUMA * numaMakeConstant(l_float32 val, l_int32 size)
numaMakeConstant()
Definition: numafunc1.c:851
NUMA * genConstrainedNumaInRange(l_int32 first, l_int32 last, l_int32 nmax, l_int32 use_pairs)
genConstrainedNumaInRange()
Definition: numafunc2.c:3278
l_ok pixaConvertToPdf(PIXA *pixa, l_int32 res, l_float32 scalefactor, l_int32 type, l_int32 quality, const char *title, const char *fileout)
pixaConvertToPdf()
Definition: pdfio1.c:790
l_ok pixSetColormap(PIX *pix, PIXCMAP *colormap)
pixSetColormap()
Definition: pix1.c:1699
l_ok pixSetResolution(PIX *pix, l_int32 xres, l_int32 yres)
pixSetResolution()
Definition: pix1.c:1387
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
l_ok pixSetText(PIX *pix, const char *textstring)
pixSetText()
Definition: pix1.c:1536
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:593
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
char * pixGetText(PIX *pix)
pixGetText()
Definition: pix1.c:1512
PIX * pixAddBlackOrWhiteBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_int32 op)
pixAddBlackOrWhiteBorder()
Definition: pix2.c:1863
l_ok pixSetAll(PIX *pix)
pixSetAll()
Definition: pix2.c:817
PIX * pixAddBorder(PIX *pixs, l_int32 npix, l_uint32 val)
pixAddBorder()
Definition: pix2.c:1823
l_ok pixSetBlackOrWhite(PIX *pixs, l_int32 op)
pixSetBlackOrWhite()
Definition: pix2.c:1021
PIX * pixAddBorderGeneral(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_uint32 val)
pixAddBorderGeneral()
Definition: pix2.c:1917
l_ok pixSetAllArbitrary(PIX *pix, l_uint32 val)
pixSetAllArbitrary()
Definition: pix2.c:951
@ L_SELECT_IF_LTE
Definition: pix.h:784
@ L_SELECT_IF_BOTH
Definition: pix.h:806
@ L_ADD_LEFT
Definition: pix.h:1211
@ L_ADD_BELOW
Definition: pix.h:1210
@ L_COPY
Definition: pix.h:712
@ L_CLONE
Definition: pix.h:713
@ L_NOCOPY
Definition: pix.h:710
@ L_INSERT
Definition: pix.h:711
#define PIX_PAINT
Definition: pix.h:336
@ L_SET_WHITE
Definition: pix.h:906
@ L_ADD_TRAIL_SLASH
Definition: pix.h:1288
#define PIX_SRC
Definition: pix.h:330
@ L_GET_BLACK_VAL
Definition: pix.h:916
@ L_GET_WHITE_VAL
Definition: pix.h:915
l_ok pixaAddPix(PIXA *pixa, PIX *pix, l_int32 copyflag)
pixaAddPix()
Definition: pixabasic.c:506
BOXA * pixaaGetBoxa(PIXAA *paa, l_int32 accesstype)
pixaaGetBoxa()
Definition: pixabasic.c:2244
PIXA * pixaCreateFromBoxa(PIX *pixs, BOXA *boxa, l_int32 start, l_int32 num, l_int32 *pcropwarn)
pixaCreateFromBoxa()
Definition: pixabasic.c:272
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_ok pixaSetText(PIXA *pixa, const char *text, SARRAY *sa)
pixaSetText()
Definition: pixabasic.c:1155
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_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
PIXA * pixaInterleave(PIXA *pixa1, PIXA *pixa2, l_int32 copyflag)
pixaInterleave()
Definition: pixabasic.c:1729
l_ok pixaGetBoxGeometry(PIXA *pixa, l_int32 index, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
pixaGetBoxGeometry()
Definition: pixabasic.c:854
l_ok pixaWriteDebug(const char *fname, PIXA *pixa)
pixaWriteDebug()
Definition: pixabasic.c:2749
l_int32 pixaaGetCount(PIXAA *paa, NUMA **pna)
pixaaGetCount()
Definition: pixabasic.c:2157
l_ok pixaJoin(PIXA *pixad, PIXA *pixas, l_int32 istart, l_int32 iend)
pixaJoin()
Definition: pixabasic.c:1673
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
l_ok pixaSizeRange(PIXA *pixa, l_int32 *pminw, l_int32 *pminh, l_int32 *pmaxw, l_int32 *pmaxh)
pixaSizeRange()
Definition: pixafunc1.c:2591
l_ok pixaAnyColormaps(PIXA *pixa, l_int32 *phascmap)
pixaAnyColormaps()
Definition: pixafunc1.c:2845
PIXA * pixaSelectRange(PIXA *pixas, l_int32 first, l_int32 last, l_int32 copyflag)
pixaSelectRange()
Definition: pixafunc1.c:1809
PIXA * pixaConvertToSameDepth(PIXA *pixas)
pixaConvertToSameDepth()
Definition: pixafunc1.c:2937
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 pixaGetDepthInfo(PIXA *pixa, l_int32 *pmaxdepth, l_int32 *psame)
pixaGetDepthInfo()
Definition: pixafunc1.c:2884
PIXA * pixaDisplayMultiTiled(PIXA *pixas, l_int32 nx, l_int32 ny, l_int32 maxw, l_int32 maxh, l_float32 scalefactor, l_int32 spacing, l_int32 border)
pixaDisplayMultiTiled()
Definition: pixafunc2.c:2315
PIX * pixaDisplay(PIXA *pixa, l_int32 w, l_int32 h)
pixaDisplay()
Definition: pixafunc2.c:191
PIXA * pixaConstrainedSelect(PIXA *pixas, l_int32 first, l_int32 last, l_int32 nmax, l_int32 use_pairs, l_int32 copyflag)
pixaConstrainedSelect()
Definition: pixafunc2.c:1965
l_ok pixGetTileCount(PIX *pix, l_int32 *pn)
pixGetTileCount()
Definition: pixafunc2.c:2267
PIX * pixaDisplayTiledInColumns(PIXA *pixas, l_int32 nx, l_float32 scalefactor, l_int32 spacing, l_int32 border)
pixaDisplayTiledInColumns()
Definition: pixafunc2.c:930
PIXA * pixaMakeFromTiledPixa(PIXA *pixas, l_int32 w, l_int32 h, l_int32 nsamp)
pixaMakeFromTiledPixa()
Definition: pixafunc2.c:2112
PIXA * pixaConvertTo32(PIXA *pixas)
pixaConvertTo32()
Definition: pixafunc2.c:1912
PIX * pixaDisplayLinearly(PIXA *pixas, l_int32 direction, l_float32 scalefactor, l_int32 background, l_int32 spacing, l_int32 border, BOXA **pboxa)
pixaDisplayLinearly()
Definition: pixafunc2.c:343
PIXA * pixaConvertTo8Colormap(PIXA *pixas, l_int32 dither)
pixaConvertTo8Colormap()
Definition: pixafunc2.c:1870
PIX * pixaaDisplayByPixa(PIXAA *paa, l_int32 maxnx, l_float32 scalefactor, l_int32 hspacing, l_int32 vspacing, l_int32 border)
pixaaDisplayByPixa()
Definition: pixafunc2.c:1675
PIX * pixaDisplayPairTiledInColumns(PIXA *pixas1, PIXA *pixas2, l_int32 nx, l_float32 scalefactor, l_int32 spacing1, l_int32 spacing2, l_int32 border1, l_int32 border2, l_int32 fontsize, l_int32 startindex, SARRAY *sa)
pixaDisplayPairTiledInColumns()
Definition: pixafunc2.c:1420
PIX * pixaDisplayTiled(PIXA *pixa, l_int32 maxwidth, l_int32 background, l_int32 spacing)
pixaDisplayTiled()
Definition: pixafunc2.c:632
l_ok pixaSplitIntoFiles(PIXA *pixas, l_int32 nsplit, l_float32 scale, l_int32 outwidth, l_int32 write_pixa, l_int32 write_pix, l_int32 write_pdf)
pixaSplitIntoFiles()
Definition: pixafunc2.c:2394
PIX * pixaaDisplay(PIXAA *paa, l_int32 w, l_int32 h)
pixaaDisplay()
Definition: pixafunc2.c:1572
PIX * pixaDisplayTiledAndScaled(PIXA *pixa, l_int32 outdepth, l_int32 tilewidth, l_int32 ncols, l_int32 background, l_int32 spacing, l_int32 border)
pixaDisplayTiledAndScaled()
Definition: pixafunc2.c:1045
PIX * pixaDisplayTiledWithText(PIXA *pixa, l_int32 maxwidth, l_float32 scalefactor, l_int32 spacing, l_int32 border, l_int32 fontsize, l_uint32 textcolor)
pixaDisplayTiledWithText()
Definition: pixafunc2.c:1200
l_ok pixaCompareInPdf(PIXA *pixa1, PIXA *pixa2, l_int32 nx, l_int32 ny, l_int32 tw, l_int32 spacing, l_int32 border, l_int32 fontsize, const char *fileout)
pixaCompareInPdf()
Definition: pixafunc2.c:2724
l_ok convertToNUpFiles(const char *dir, const char *substr, l_int32 nx, l_int32 ny, l_int32 tw, l_int32 spacing, l_int32 border, l_int32 fontsize, const char *outdir)
convertToNUpFiles()
Definition: pixafunc2.c:2483
PIX * pixaDisplayTiledByIndex(PIXA *pixa, NUMA *na, l_int32 width, l_int32 spacing, l_int32 border, l_int32 fontsize, l_uint32 textcolor)
pixaDisplayTiledByIndex()
Definition: pixafunc2.c:1296
PIXA * pixaConvertToNUpPixa(PIXA *pixas, SARRAY *sa, l_int32 nx, l_int32 ny, l_int32 tw, l_int32 spacing, l_int32 border, l_int32 fontsize)
pixaConvertToNUpPixa()
Definition: pixafunc2.c:2611
PIX * pixaDisplayRandomCmap(PIXA *pixa, l_int32 w, l_int32 h)
pixaDisplayRandomCmap()
Definition: pixafunc2.c:269
PIXA * pixaConvertTo1(PIXA *pixas, l_int32 thresh)
pixaConvertTo1()
Definition: pixafunc2.c:1788
PIXA * pixaaDisplayTiledAndScaled(PIXAA *paa, l_int32 outdepth, l_int32 tilewidth, l_int32 ncols, l_int32 background, l_int32 spacing, l_int32 border)
pixaaDisplayTiledAndScaled()
Definition: pixafunc2.c:1738
PIX * pixaDisplayTiledInRows(PIXA *pixa, l_int32 outdepth, l_int32 maxwidth, l_float32 scalefactor, l_int32 background, l_int32 spacing, l_int32 border)
pixaDisplayTiledInRows()
Definition: pixafunc2.c:746
PIX * pixaDisplayUnsplit(PIXA *pixa, l_int32 nx, l_int32 ny, l_int32 borderwidth, l_uint32 bordercolor)
pixaDisplayUnsplit()
Definition: pixafunc2.c:557
PIXA * pixaMakeFromTiledPix(PIX *pixs, l_int32 w, l_int32 h, l_int32 start, l_int32 num, BOXA *boxa)
pixaMakeFromTiledPix()
Definition: pixafunc2.c:2192
PIXA * convertToNUpPixa(const char *dir, const char *substr, l_int32 nx, l_int32 ny, l_int32 tw, l_int32 spacing, l_int32 border, l_int32 fontsize)
convertToNUpPixa()
Definition: pixafunc2.c:2545
PIX * pixaDisplayOnLattice(PIXA *pixa, l_int32 cellw, l_int32 cellh, l_int32 *pncols, BOXA **pboxa)
pixaDisplayOnLattice()
Definition: pixafunc2.c:440
l_ok pixaSelectToPdf(PIXA *pixas, l_int32 first, l_int32 last, l_int32 res, l_float32 scalefactor, l_int32 type, l_int32 quality, l_uint32 color, l_int32 fontsize, const char *fileout)
pixaSelectToPdf()
Definition: pixafunc2.c:2033
PIXA * pixaConvertTo8(PIXA *pixas, l_int32 cmapflag)
pixaConvertTo8()
Definition: pixafunc2.c:1829
PIX * pixConvertTo8(PIX *pixs, l_int32 cmapflag)
pixConvertTo8()
Definition: pixconv.c:3133
PIX * pixConvertTo8Colormap(PIX *pixs, l_int32 dither)
pixConvertTo8Colormap()
Definition: pixconv.c:3248
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3332
PIX * pixConvertTo1(PIX *pixs, l_int32 threshold)
pixConvertTo1()
Definition: pixconv.c:3026
PIX * pixConvert1To8(PIX *pixd, PIX *pixs, l_uint8 val0, l_uint8 val1)
pixConvert1To8()
Definition: pixconv.c:2401
PIXA * pixaReadFilesSA(SARRAY *sa)
pixaReadFilesSA()
Definition: readfile.c:154
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
SARRAY * getSortedPathnamesInDirectory(const char *dirname, const char *substr, l_int32 first, l_int32 nfiles)
getSortedPathnamesInDirectory()
Definition: sarray1.c:1848
SARRAY * sarrayCreate(l_int32 n)
sarrayCreate()
Definition: sarray1.c:170
char * sarrayGetString(SARRAY *sa, l_int32 index, l_int32 copyflag)
sarrayGetString()
Definition: sarray1.c:703
l_int32 sarrayGetCount(SARRAY *sa)
sarrayGetCount()
Definition: sarray1.c:643
void sarrayDestroy(SARRAY **psa)
sarrayDestroy()
Definition: sarray1.c:362
l_ok sarrayAddString(SARRAY *sa, const char *string, l_int32 copyflag)
sarrayAddString()
Definition: sarray1.c:451
SARRAY * sarrayGenerateIntegers(l_int32 n)
sarrayGenerateIntegers()
Definition: sarray2.c:625
PIX * pixScale(PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScale()
Definition: scale1.c:250
PIX * pixScaleToSize(PIX *pixs, l_int32 wd, l_int32 hd)
pixScaleToSize()
Definition: scale1.c:323
PIX * pixScaleToGray(PIX *pixs, l_float32 scalefactor)
pixScaleToGray()
Definition: scale2.c:208
Definition: pix.h:481
Definition: pix.h:492
Definition: bmf.h:47
Definition: array.h:71
Definition: pix.h:139
Definition: pix.h:456
Definition: pix.h:467
Definition: array.h:127
PIXA * pixaAddTextNumber(PIXA *pixas, L_BMF *bmf, NUMA *na, l_uint32 val, l_int32 location)
pixaAddTextNumber()
Definition: textops.c:649
PIX * pixAddTextlines(PIX *pixs, L_BMF *bmf, const char *textstr, l_uint32 val, l_int32 location)
pixAddTextlines()
Definition: textops.c:276
PIX * pixAddSingleTextblock(PIX *pixs, L_BMF *bmf, const char *textstr, l_uint32 val, l_int32 location, l_int32 *poverflow)
pixAddSingleTextblock()
Definition: textops.c:120
void lept_stderr(const char *fmt,...)
lept_stderr()
Definition: utils1.c:306
l_int32 lept_roundftoi(l_float32 fval)
lept_roundftoi()
Definition: utils1.c:700
l_int32 lept_rmdir(const char *subdir)
lept_rmdir()
Definition: utils2.c:2295
l_ok modifyTrailingSlash(char *path, size_t nbytes, l_int32 flag)
modifyTrailingSlash()
Definition: utils2.c:3347
l_ok splitPathAtDirectory(const char *pathname, char **pdir, char **ptail)
splitPathAtDirectory()
Definition: utils2.c:2824
l_int32 lept_mkdir(const char *subdir)
lept_mkdir()
Definition: utils2.c:2218
l_ok makeTempDirname(char *result, size_t nbytes, const char *subdir)
makeTempDirname()
Definition: utils2.c:3282