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  *---------------------------------------------------------------------*/
190 PIX *
192  l_int32 w,
193  l_int32 h)
194 {
195 l_int32 i, n, d, xb, yb, wb, hb, res;
196 BOXA *boxa;
197 PIX *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 
268 PIX *
270  l_int32 w,
271  l_int32 h)
272 {
273 l_int32 i, n, same, maxd, index, xb, yb, wb, hb, res;
274 BOXA *boxa;
275 PIX *pixs, *pix1, *pixd;
276 PIXCMAP *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 
342 PIX *
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 {
351 l_int32 i, n, x, y, w, h, size, depth, bordval;
352 BOX *box;
353 PIX *pix1, *pix2, *pix3, *pixd;
354 PIXA *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 
439 PIX *
441  l_int32 cellw,
442  l_int32 cellh,
443  l_int32 *pncols,
444  BOXA **pboxa)
445 {
446 char buf[16];
447 l_int32 n, nw, nh, w, h, d, wt, ht, res, samedepth;
448 l_int32 index, i, j, hascmap;
449 BOX *box;
450 BOXA *boxa;
451 PIX *pix1, *pix2, *pixd;
452 PIXA *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 
556 PIX *
558  l_int32 nx,
559  l_int32 ny,
560  l_int32 borderwidth,
561  l_uint32 bordercolor)
562 {
563 l_int32 w, h, d, wt, ht;
564 l_int32 i, j, k, x, y, n;
565 PIX *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 
631 PIX *
633  l_int32 maxwidth,
634  l_int32 background,
635  l_int32 spacing)
636 {
637 l_int32 wmax, hmax, wd, hd, d, hascmap, res, same;
638 l_int32 i, j, n, ni, ncols, nrows;
639 l_int32 ystart, xstart, wt, ht;
640 PIX *pix1, *pix2, *pixd;
641 PIXA *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 
745 PIX *
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 {
754 l_int32 h; /* cumulative height over all the rows */
755 l_int32 w; /* cumulative height in the current row */
756 l_int32 bordval, wtry, wt, ht;
757 l_int32 irow; /* index of current pix in current row */
758 l_int32 wmaxrow; /* width of the largest row */
759 l_int32 maxh; /* max height in row */
760 l_int32 i, j, index, n, x, y, nrows, ninrow, res;
761 size_t size;
762 l_uint8 *data;
763 BOXA *boxa;
764 NUMA *nainrow; /* number of pix in the row */
765 NUMA *namaxh; /* height of max pix in the row */
766 PIX *pix, *pixn, *pix1, *pixd;
767 PIXA *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 
929 PIX *
931  l_int32 nx,
932  l_float32 scalefactor,
933  l_int32 spacing,
934  l_int32 border)
935 {
936 l_int32 i, j, index, n, x, y, nrows, wb, hb, w, h, maxd, maxh, bordval, res;
937 size_t size;
938 l_uint8 *data;
939 BOX *box;
940 BOXA *boxa;
941 PIX *pix1, *pix2, *pix3, *pixd;
942 PIXA *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 
1044 PIX *
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 {
1053 l_int32 x, y, w, h, wd, hd, d, res;
1054 l_int32 i, n, nrows, maxht, ninrow, irow, bordval;
1055 l_int32 *rowht;
1056 l_float32 scalefact;
1057 PIX *pix, *pixn, *pix1, *pixb, *pixd;
1058 PIXA *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 
1199 PIX *
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 {
1208 char buf[128];
1209 char *textstr;
1210 l_int32 i, n, maxw;
1211 L_BMF *bmf;
1212 PIX *pix1, *pix2, *pix3, *pix4, *pixd;
1213 PIXA *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 
1295 PIX *
1297  NUMA *na,
1298  l_int32 width,
1299  l_int32 spacing,
1300  l_int32 border,
1301  l_int32 fontsize,
1302  l_uint32 textcolor)
1303 {
1304 char buf[128];
1305 char *textstr;
1306 l_int32 i, n, x, y, w, h, yval, index;
1307 l_float32 maxindex;
1308 L_BMF *bmf;
1309 BOX *box;
1310 NUMA *nay; /* top of the next pix to add in that column */
1311 PIX *pix1, *pix2, *pix3, *pix4, *pix5, *pixd;
1312 PIXA *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  *---------------------------------------------------------------------*/
1419 PIX *
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 {
1432 l_int32 i, n, w, maxd, maxd1, maxd2, res, text;
1433 NUMA *na;
1434 PIX *pixs1, *pixs2, *pix1, *pix2, *pix3, *pix4;
1435 PIX *pix5, *pix6, *pix7, *pix8, *pix9;
1436 PIXA *pixa1, *pixa2;
1437 SARRAY *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  *---------------------------------------------------------------------*/
1571 PIX *
1573  l_int32 w,
1574  l_int32 h)
1575 {
1576 l_int32 i, j, n, nbox, na, d, wmax, hmax, x, y, xb, yb, wb, hb;
1577 BOXA *boxa1; /* top-level boxa */
1578 BOXA *boxa;
1579 PIX *pix1, *pixd;
1580 PIXA *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 
1674 PIX *
1676  l_int32 maxnx,
1677  l_float32 scalefactor,
1678  l_int32 hspacing,
1679  l_int32 vspacing,
1680  l_int32 border)
1681 {
1682 l_int32 i, n, vs;
1683 PIX *pix1, *pix2;
1684 PIXA *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 
1737 PIXA *
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 {
1746 l_int32 i, n;
1747 PIX *pix;
1748 PIXA *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  *---------------------------------------------------------------------*/
1787 PIXA *
1789  l_int32 thresh)
1790 {
1791 l_int32 i, n;
1792 BOXA *boxa;
1793 PIX *pix1, *pix2;
1794 PIXA *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 
1828 PIXA *
1830  l_int32 cmapflag)
1831 {
1832 l_int32 i, n;
1833 BOXA *boxa;
1834 PIX *pix1, *pix2;
1835 PIXA *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 
1869 PIXA *
1871  l_int32 dither)
1872 {
1873 l_int32 i, n;
1874 BOXA *boxa;
1875 PIX *pix1, *pix2;
1876 PIXA *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 
1911 PIXA *
1913 {
1914 l_int32 i, n;
1915 BOXA *boxa;
1916 PIX *pix1, *pix2;
1917 PIXA *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  *---------------------------------------------------------------------*/
1964 PIXA *
1966  l_int32 first,
1967  l_int32 last,
1968  l_int32 nmax,
1969  l_int32 use_pairs,
1970  l_int32 copyflag)
1971 {
1972 l_int32 i, n, nselect, index;
1973 NUMA *na;
1974 PIX *pix1;
1975 PIXA *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 
2032 l_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 {
2044 l_int32 n;
2045 L_BMF *bmf;
2046 NUMA *na;
2047 PIXA *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  *---------------------------------------------------------------------*/
2111 PIXA *
2113  l_int32 w,
2114  l_int32 h,
2115  l_int32 nsamp)
2116 {
2117 char buf[8];
2118 l_int32 ntiles, i;
2119 PIX *pix1;
2120 PIXA *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 
2191 PIXA *
2193  l_int32 w,
2194  l_int32 h,
2195  l_int32 start,
2196  l_int32 num,
2197  BOXA *boxa)
2198 {
2199 l_int32 i, j, k, ws, hs, d, nx, ny, n, n_isvalid, ntiles, nmax;
2200 PIX *pix1;
2201 PIXA *pixa1;
2202 PIXCMAP *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 
2266 l_ok
2268  l_int32 *pn)
2269 {
2270 char *text;
2271 l_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  *---------------------------------------------------------------------*/
2314 PIXA *
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 {
2324 l_int32 n, i, j, ntile, nout, index;
2325 PIX *pix1, *pix2;
2326 PIXA *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  *---------------------------------------------------------------------*/
2393 l_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 {
2402 char buf[64];
2403 l_int32 i, j, index, n, nt;
2404 PIX *pix1, *pix2;
2405 PIXA *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  *---------------------------------------------------------------------*/
2482 l_ok
2483 convertToNUpFiles(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 {
2493 l_int32 d, format;
2494 char rootpath[256];
2495 PIXA *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 
2544 PIXA *
2545 convertToNUpPixa(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 {
2554 l_int32 i, n;
2555 char *fname, *tail;
2556 PIXA *pixa1, *pixa2;
2557 SARRAY *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 
2610 PIXA *
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 {
2620 l_int32 i, j, k, nt, n2, nout, d;
2621 char *str;
2622 L_BMF *bmf;
2623 PIX *pix1, *pix2, *pix3, *pix4;
2624 PIXA *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  *---------------------------------------------------------------------*/
2723 l_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 {
2734 l_int32 n1, n2, npairs;
2735 PIXA *pixa3, *pixa4, *pixa5;
2736 SARRAY *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 
PIX * pixaaDisplay(PIXAA *paa, l_int32 w, l_int32 h)
pixaaDisplay()
Definition: pixafunc2.c:1572
PIXA * pixaInterleave(PIXA *pixa1, PIXA *pixa2, l_int32 copyflag)
pixaInterleave()
Definition: pixabasic.c:1729
void bmfDestroy(L_BMF **pbmf)
bmfDestroy()
Definition: bmf.c:169
PIX * pixConvertTo1(PIX *pixs, l_int32 threshold)
pixConvertTo1()
Definition: pixconv.c:3026
l_int32 lept_mkdir(const char *subdir)
lept_mkdir()
Definition: utils2.c:2218
PIX * pixScaleToGray(PIX *pixs, l_float32 scalefactor)
pixScaleToGray()
Definition: scale2.c:208
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3332
l_int32 lept_roundftoi(l_float32 fval)
lept_roundftoi()
Definition: utils1.c:700
l_ok pixaSetText(PIXA *pixa, const char *text, SARRAY *sa)
pixaSetText()
Definition: pixabasic.c:1155
SARRAY * sarrayGenerateIntegers(l_int32 n)
sarrayGenerateIntegers()
Definition: sarray2.c:625
l_ok pixaWriteDebug(const char *fname, PIXA *pixa)
pixaWriteDebug()
Definition: pixabasic.c:2749
l_ok pixaVerifyDepth(PIXA *pixa, l_int32 *psame, l_int32 *pmaxd)
pixaVerifyDepth()
Definition: pixabasic.c:960
Definition: pix.h:713
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:478
PIXA * pixaCreate(l_int32 n)
pixaCreate()
Definition: pixabasic.c:167
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
l_ok pixaSetBoxa(PIXA *pixa, BOXA *boxa, l_int32 accesstype)
pixaSetBoxa()
Definition: pixabasic.c:896
Definition: pix.h:712
l_ok pixaJoin(PIXA *pixad, PIXA *pixas, l_int32 istart, l_int32 iend)
pixaJoin()
Definition: pixabasic.c:1673
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
PIXA * pixaaGetPixa(PIXAA *paa, l_int32 index, l_int32 accesstype)
pixaaGetPixa()
Definition: pixabasic.c:2206
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
PIX * pixaDisplayUnsplit(PIXA *pixa, l_int32 nx, l_int32 ny, l_int32 borderwidth, l_uint32 bordercolor)
pixaDisplayUnsplit()
Definition: pixafunc2.c:557
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 * pixConvertTo8(PIX *pixs, l_int32 cmapflag)
pixConvertTo8()
Definition: pixconv.c:3133
l_int32 pixaaGetCount(PIXAA *paa, NUMA **pna)
pixaaGetCount()
Definition: pixabasic.c:2157
NUMA * numaMakeConstant(l_float32 val, l_int32 size)
numaMakeConstant()
Definition: numafunc1.c:851
void lept_stderr(const char *fmt,...)
lept_stderr()
Definition: utils1.c:306
Definition: pix.h:710
PIX * pixaDisplayOnLattice(PIXA *pixa, l_int32 cellw, l_int32 cellh, l_int32 *pncols, BOXA **pboxa)
pixaDisplayOnLattice()
Definition: pixafunc2.c:440
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:315
SARRAY * sarrayCreate(l_int32 n)
sarrayCreate()
Definition: sarray1.c:170
l_ok pixSetAll(PIX *pix)
pixSetAll()
Definition: pix2.c:817
PIXA * pixaConvertToSameDepth(PIXA *pixas)
pixaConvertToSameDepth()
Definition: pixafunc1.c:2937
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:194
l_ok pixaGetDepthInfo(PIXA *pixa, l_int32 *pmaxdepth, l_int32 *psame)
pixaGetDepthInfo()
Definition: pixafunc1.c:2884
void boxaDestroy(BOXA **pboxa)
boxaDestroy()
Definition: boxbasic.c:583
PIX * pixAddBlackOrWhiteBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_int32 op)
pixAddBlackOrWhiteBorder()
Definition: pix2.c:1863
PIXA * pixaCreateFromBoxa(PIX *pixs, BOXA *boxa, l_int32 start, l_int32 num, l_int32 *pcropwarn)
pixaCreateFromBoxa()
Definition: pixabasic.c:272
PIX * pixaDisplay(PIXA *pixa, l_int32 w, l_int32 h)
pixaDisplay()
Definition: pixafunc2.c:191
Definition: pix.h:491
PIX * pixaDisplayTiledInColumns(PIXA *pixas, l_int32 nx, l_float32 scalefactor, l_int32 spacing, l_int32 border)
pixaDisplayTiledInColumns()
Definition: pixafunc2.c:930
l_ok numaSetValue(NUMA *na, l_int32 index, l_float32 val)
numaSetValue()
Definition: numabasic.c:786
l_ok pixSetColormap(PIX *pix, PIXCMAP *colormap)
pixSetColormap()
Definition: pix1.c:1699
l_ok modifyTrailingSlash(char *path, size_t nbytes, l_int32 flag)
modifyTrailingSlash()
Definition: utils2.c:3347
Definition: bmf.h:46
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
Definition: array.h:126
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 * pixAddBorder(PIX *pixs, l_int32 npix, l_uint32 val)
pixAddBorder()
Definition: pix2.c:1823
PIXA * pixaConvertTo8(PIXA *pixas, l_int32 cmapflag)
pixaConvertTo8()
Definition: pixafunc2.c:1829
l_ok pixSetText(PIX *pix, const char *textstring)
pixSetText()
Definition: pix1.c:1536
l_ok pixSetAllArbitrary(PIX *pix, l_uint32 val)
pixSetAllArbitrary()
Definition: pix2.c:951
PIXA * pixaCopy(PIXA *pixa, l_int32 copyflag)
pixaCopy()
Definition: pixabasic.c:453
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
NUMA * genConstrainedNumaInRange(l_int32 first, l_int32 last, l_int32 nmax, l_int32 use_pairs)
genConstrainedNumaInRange()
Definition: numafunc2.c:3278
PIX * pixaDisplayRandomCmap(PIXA *pixa, l_int32 w, l_int32 h)
pixaDisplayRandomCmap()
Definition: pixafunc2.c:269
l_ok numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition: numabasic.c:754
l_ok pixaAddPix(PIXA *pixa, PIX *pix, l_int32 copyflag)
pixaAddPix()
Definition: pixabasic.c:506
Definition: array.h:70
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
l_int32 numaGetCount(NUMA *na)
numaGetCount()
Definition: numabasic.c:658
l_ok sarrayAddString(SARRAY *sa, const char *string, l_int32 copyflag)
sarrayAddString()
Definition: sarray1.c:451
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
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
l_ok boxaAddBox(BOXA *boxa, BOX *box, l_int32 copyflag)
boxaAddBox()
Definition: boxbasic.c:620
PIXA * pixaSelectBySize(PIXA *pixas, l_int32 width, l_int32 height, l_int32 type, l_int32 relation, l_int32 *pchanged)
pixaSelectBySize()
Definition: pixafunc1.c:306
PIX * pixConvertTo8Colormap(PIX *pixs, l_int32 dither)
pixConvertTo8Colormap()
Definition: pixconv.c:3248
l_ok pixSetBlackOrWhite(PIX *pixs, l_int32 op)
pixSetBlackOrWhite()
Definition: pix2.c:1021
l_ok pixGetTileCount(PIX *pix, l_int32 *pn)
pixGetTileCount()
Definition: pixafunc2.c:2267
char * sarrayGetString(SARRAY *sa, l_int32 index, l_int32 copyflag)
sarrayGetString()
Definition: sarray1.c:703
#define PIX_PAINT
Definition: pix.h:336
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
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 * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:593
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 * pixScaleToSize(PIX *pixs, l_int32 wd, l_int32 hd)
pixScaleToSize()
Definition: scale1.c:323
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:621
NUMA * numaMakeSequence(l_float32 startval, l_float32 increment, l_int32 size)
numaMakeSequence()
Definition: numafunc1.c:821
Definition: pix.h:711
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
SARRAY * getSortedPathnamesInDirectory(const char *dirname, const char *substr, l_int32 first, l_int32 nfiles)
getSortedPathnamesInDirectory()
Definition: sarray1.c:1848
l_ok boxaWriteMem(l_uint8 **pdata, size_t *psize, BOXA *boxa)
boxaWriteMem()
Definition: boxbasic.c:2371
Definition: pix.h:455
l_ok boxaGetExtent(BOXA *boxa, l_int32 *pw, l_int32 *ph, BOX **pbox)
boxaGetExtent()
Definition: boxfunc4.c:953
l_ok splitPathAtDirectory(const char *pathname, char **pdir, char **ptail)
splitPathAtDirectory()
Definition: utils2.c:2824
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
PIXA * pixaReadFilesSA(SARRAY *sa)
pixaReadFilesSA()
Definition: readfile.c:154
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:366
Definition: pix.h:466
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1113
PIXA * pixaMakeFromTiledPixa(PIXA *pixas, l_int32 w, l_int32 h, l_int32 nsamp)
pixaMakeFromTiledPixa()
Definition: pixafunc2.c:2112
l_ok pixaSizeRange(PIXA *pixa, l_int32 *pminw, l_int32 *pminh, l_int32 *pmaxw, l_int32 *pmaxh)
pixaSizeRange()
Definition: pixafunc1.c:2591
l_int32 sarrayGetCount(SARRAY *sa)
sarrayGetCount()
Definition: sarray1.c:643
char * pixGetText(PIX *pix)
pixGetText()
Definition: pix1.c:1512
l_ok pixaGetRenderingDepth(PIXA *pixa, l_int32 *pdepth)
pixaGetRenderingDepth()
Definition: pixafunc1.c:2767
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
PIX * pixaGetPix(PIXA *pixa, l_int32 index, l_int32 accesstype)
pixaGetPix()
Definition: pixabasic.c:691
Definition: pix.h:138
PIXA * pixaMakeFromTiledPix(PIX *pixs, l_int32 w, l_int32 h, l_int32 start, l_int32 num, BOXA *boxa)
pixaMakeFromTiledPix()
Definition: pixafunc2.c:2192
l_ok makeTempDirname(char *result, size_t nbytes, const char *subdir)
makeTempDirname()
Definition: utils2.c:3282
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
l_ok pixaGetPixDimensions(PIXA *pixa, l_int32 index, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixaGetPixDimensions()
Definition: pixabasic.c:726
BOXA * boxaCreate(l_int32 n)
boxaCreate()
Definition: boxbasic.c:502
#define PIX_SRC
Definition: pix.h:330
PIXA * pixaConvertTo32(PIXA *pixas)
pixaConvertTo32()
Definition: pixafunc2.c:1912
l_ok pixCopyColormap(PIX *pixd, const PIX *pixs)
pixCopyColormap()
Definition: pix1.c:816
PIX * pixConvert1To8(PIX *pixd, PIX *pixs, l_uint8 val0, l_uint8 val1)
pixConvert1To8()
Definition: pixconv.c:2401
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
PIXA * pixaConvertTo8Colormap(PIXA *pixas, l_int32 dither)
pixaConvertTo8Colormap()
Definition: pixafunc2.c:1870
PIX * pixAddTextlines(PIX *pixs, L_BMF *bmf, const char *textstr, l_uint32 val, l_int32 location)
pixAddTextlines()
Definition: textops.c:276
l_int32 boxaGetCount(BOXA *boxa)
boxaGetCount()
Definition: boxbasic.c:734
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
BOXA * pixaaGetBoxa(PIXAA *paa, l_int32 accesstype)
pixaaGetBoxa()
Definition: pixabasic.c:2244
l_ok pixSetResolution(PIX *pix, l_int32 xres, l_int32 yres)
pixSetResolution()
Definition: pix1.c:1387
PIXA * pixaConvertTo1(PIXA *pixas, l_int32 thresh)
pixaConvertTo1()
Definition: pixafunc2.c:1788
l_ok numaGetMax(NUMA *na, l_float32 *pmaxval, l_int32 *pimaxloc)
numaGetMax()
Definition: numafunc1.c:496
PIXA * pixaSelectRange(PIXA *pixas, l_int32 first, l_int32 last, l_int32 copyflag)
pixaSelectRange()
Definition: pixafunc1.c:1809
l_int32 lept_rmdir(const char *subdir)
lept_rmdir()
Definition: utils2.c:2295
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
PIXCMAP * pixcmapCopy(const PIXCMAP *cmaps)
pixcmapCopy()
Definition: colormap.c:248
SARRAY * numaConvertToSarray(NUMA *na, l_int32 size1, l_int32 size2, l_int32 addzeros, l_int32 type)
numaConvertToSarray()
Definition: numabasic.c:1054
l_ok pixaAddBox(PIXA *pixa, BOX *box, l_int32 copyflag)
pixaAddBox()
Definition: pixabasic.c:555
Definition: pix.h:480
PIX * pixScale(PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScale()
Definition: scale1.c:250
void pixaDestroy(PIXA **ppixa)
pixaDestroy()
Definition: pixabasic.c:412
PIX * pixAddSingleTextblock(PIX *pixs, L_BMF *bmf, const char *textstr, l_uint32 val, l_int32 location, l_int32 *poverflow)
pixAddSingleTextblock()
Definition: textops.c:120
BOX * boxCreate(l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxCreate()
Definition: boxbasic.c:172
l_int32 pixaGetCount(PIXA *pixa)
pixaGetCount()
Definition: pixabasic.c:650
PIX * pixAddBorderGeneral(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_uint32 val)
pixAddBorderGeneral()
Definition: pix2.c:1917
PIXA * pixaAddTextNumber(PIXA *pixas, L_BMF *bmf, NUMA *na, l_uint32 val, l_int32 location)
pixaAddTextNumber()
Definition: textops.c:649
void sarrayDestroy(SARRAY **psa)
sarrayDestroy()
Definition: sarray1.c:362
PIX * pixaDisplayTiled(PIXA *pixa, l_int32 maxwidth, l_int32 background, l_int32 spacing)
pixaDisplayTiled()
Definition: pixafunc2.c:632
l_ok pixaAnyColormaps(PIXA *pixa, l_int32 *phascmap)
pixaAnyColormaps()
Definition: pixafunc1.c:2845
PIXCMAP * pixcmapCreateRandom(l_int32 depth, l_int32 hasblack, l_int32 haswhite)
pixcmapCreateRandom()
Definition: colormap.c:172
L_BMF * bmfCreate(const char *dir, l_int32 fontsize)
bmfCreate()
Definition: bmf.c:117
BOXA * pixaGetBoxa(PIXA *pixa, l_int32 accesstype)
pixaGetBoxa()
Definition: pixabasic.c:760