Leptonica  1.73
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 
150 #include <string.h>
151 #include <math.h> /* for sqrt() */
152 #include "allheaders.h"
153 
154 
155 /*---------------------------------------------------------------------*
156  * Pixa Display *
157  *---------------------------------------------------------------------*/
178 PIX *
180  l_int32 w,
181  l_int32 h)
182 {
183 l_int32 i, n, d, xb, yb, wb, hb, res;
184 BOXA *boxa;
185 PIX *pix1, *pixd;
186 
187  PROCNAME("pixaDisplay");
188 
189  if (!pixa)
190  return (PIX *)ERROR_PTR("pixa not defined", procName, NULL);
191 
192  n = pixaGetCount(pixa);
193  if (n == 0 && w == 0 && h == 0)
194  return (PIX *)ERROR_PTR("no components; no size", procName, NULL);
195  if (n == 0) {
196  L_WARNING("no components; returning empty 1 bpp pix\n", procName);
197  return pixCreate(w, h, 1);
198  }
199 
200  /* If w and h not input, determine the minimum size required
201  * to contain the origin and all c.c. */
202  if (w == 0 || h == 0) {
203  boxa = pixaGetBoxa(pixa, L_CLONE);
204  boxaGetExtent(boxa, &w, &h, NULL);
205  boxaDestroy(&boxa);
206  if (w == 0 || h == 0)
207  return (PIX *)ERROR_PTR("no associated boxa", procName, NULL);
208  }
209 
210  /* Use the first pix in pixa to determine depth and resolution */
211  pix1 = pixaGetPix(pixa, 0, L_CLONE);
212  d = pixGetDepth(pix1);
213  res = pixGetXRes(pix1);
214  pixDestroy(&pix1);
215 
216  if ((pixd = pixCreate(w, h, d)) == NULL)
217  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
218  pixSetResolution(pixd, res, res);
219  if (d > 1)
220  pixSetAll(pixd);
221  for (i = 0; i < n; i++) {
222  if (pixaGetBoxGeometry(pixa, i, &xb, &yb, &wb, &hb)) {
223  L_WARNING("no box found!\n", procName);
224  continue;
225  }
226  pix1 = pixaGetPix(pixa, i, L_CLONE);
227  if (d == 1)
228  pixRasterop(pixd, xb, yb, wb, hb, PIX_PAINT, pix1, 0, 0);
229  else
230  pixRasterop(pixd, xb, yb, wb, hb, PIX_SRC, pix1, 0, 0);
231  pixDestroy(&pix1);
232  }
233 
234  return pixd;
235 }
236 
237 
258 PIX *
260  l_int32 w,
261  l_int32 h,
262  l_uint32 bgcolor)
263 {
264 l_int32 i, n, xb, yb, wb, hb, hascmap, maxdepth, same, res;
265 BOXA *boxa;
266 PIX *pix1, *pix2, *pixd;
267 PIXA *pixat;
268 
269  PROCNAME("pixaDisplayOnColor");
270 
271  if (!pixa)
272  return (PIX *)ERROR_PTR("pixa not defined", procName, NULL);
273  if ((n = pixaGetCount(pixa)) == 0)
274  return (PIX *)ERROR_PTR("no components", procName, NULL);
275 
276  /* If w and h are not input, determine the minimum size
277  * required to contain the origin and all c.c. */
278  if (w == 0 || h == 0) {
279  boxa = pixaGetBoxa(pixa, L_CLONE);
280  boxaGetExtent(boxa, &w, &h, NULL);
281  boxaDestroy(&boxa);
282  }
283 
284  /* If any pix have colormaps, or if they have different depths,
285  * generate rgb */
286  pixaAnyColormaps(pixa, &hascmap);
287  pixaGetDepthInfo(pixa, &maxdepth, &same);
288  if (hascmap || !same) {
289  maxdepth = 32;
290  pixat = pixaCreate(n);
291  for (i = 0; i < n; i++) {
292  pix1 = pixaGetPix(pixa, i, L_CLONE);
293  pix2 = pixConvertTo32(pix1);
294  pixaAddPix(pixat, pix2, L_INSERT);
295  pixDestroy(&pix1);
296  }
297  } else {
298  pixat = pixaCopy(pixa, L_CLONE);
299  }
300 
301  /* Make the output pix and set the background color */
302  if ((pixd = pixCreate(w, h, maxdepth)) == NULL) {
303  pixaDestroy(&pixat);
304  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
305  }
306  if ((maxdepth == 1 && bgcolor > 0) ||
307  (maxdepth == 2 && bgcolor >= 0x3) ||
308  (maxdepth == 4 && bgcolor >= 0xf) ||
309  (maxdepth == 8 && bgcolor >= 0xff) ||
310  (maxdepth == 16 && bgcolor >= 0xffff) ||
311  (maxdepth == 32 && bgcolor >= 0xffffff00)) {
312  pixSetAll(pixd);
313  } else if (bgcolor > 0) {
314  pixSetAllArbitrary(pixd, bgcolor);
315  }
316 
317  /* Blit each pix into its place */
318  for (i = 0; i < n; i++) {
319  if (pixaGetBoxGeometry(pixat, i, &xb, &yb, &wb, &hb)) {
320  L_WARNING("no box found!\n", procName);
321  continue;
322  }
323  pix1 = pixaGetPix(pixat, i, L_CLONE);
324  if (i == 0) res = pixGetXRes(pix1);
325  pixRasterop(pixd, xb, yb, wb, hb, PIX_SRC, pix1, 0, 0);
326  pixDestroy(&pix1);
327  }
328  pixSetResolution(pixd, res, res);
329 
330  pixaDestroy(&pixat);
331  return pixd;
332 }
333 
334 
353 PIX *
355  l_int32 w,
356  l_int32 h)
357 {
358 l_int32 i, n, same, maxd, index, xb, yb, wb, hb, res;
359 BOXA *boxa;
360 PIX *pixs, *pix1, *pixd;
361 PIXCMAP *cmap;
362 
363  PROCNAME("pixaDisplayRandomCmap");
364 
365  if (!pixa)
366  return (PIX *)ERROR_PTR("pixa not defined", procName, NULL);
367 
368  if ((n = pixaGetCount(pixa)) == 0)
369  return (PIX *)ERROR_PTR("no components", procName, NULL);
370  pixaVerifyDepth(pixa, &same, &maxd);
371  if (maxd > 1)
372  return (PIX *)ERROR_PTR("not all components are 1 bpp", procName, NULL);
373 
374  /* If w and h are not input, determine the minimum size required
375  * to contain the origin and all c.c. */
376  if (w == 0 || h == 0) {
377  boxa = pixaGetBoxa(pixa, L_CLONE);
378  boxaGetExtent(boxa, &w, &h, NULL);
379  boxaDestroy(&boxa);
380  }
381 
382  /* Set up an 8 bpp dest pix, with a colormap with 254 random colors */
383  if ((pixd = pixCreate(w, h, 8)) == NULL)
384  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
385  cmap = pixcmapCreateRandom(8, 1, 1);
386  pixSetColormap(pixd, cmap);
387 
388  /* Color each component and blit it in */
389  for (i = 0; i < n; i++) {
390  index = 1 + (i % 254);
391  pixaGetBoxGeometry(pixa, i, &xb, &yb, &wb, &hb);
392  pixs = pixaGetPix(pixa, i, L_CLONE);
393  if (i == 0) res = pixGetXRes(pixs);
394  pix1 = pixConvert1To8(NULL, pixs, 0, index);
395  pixRasterop(pixd, xb, yb, wb, hb, PIX_PAINT, pix1, 0, 0);
396  pixDestroy(&pixs);
397  pixDestroy(&pix1);
398  }
399 
400  pixSetResolution(pixd, res, res);
401  return pixd;
402 }
403 
404 
427 PIX *
429  l_int32 direction,
430  l_float32 scalefactor,
431  l_int32 background, /* not used */
432  l_int32 spacing,
433  l_int32 border,
434  BOXA **pboxa)
435 {
436 l_int32 i, n, x, y, w, h, size, depth, bordval;
437 BOX *box;
438 PIX *pix1, *pix2, *pix3, *pixd;
439 PIXA *pixa1, *pixa2;
440 
441  PROCNAME("pixaDisplayLinearly");
442 
443  if (pboxa) *pboxa = NULL;
444  if (!pixas)
445  return (PIX *)ERROR_PTR("pixas not defined", procName, NULL);
446  if (direction != L_HORIZ && direction != L_VERT)
447  return (PIX *)ERROR_PTR("invalid direction", procName, NULL);
448 
449  /* Make sure all pix are at the same depth */
450  pixa1 = pixaConvertToSameDepth(pixas);
451  pixaGetDepthInfo(pixa1, &depth, NULL);
452 
453  /* Scale and add border if requested */
454  n = pixaGetCount(pixa1);
455  pixa2 = pixaCreate(n);
456  bordval = (depth == 1) ? 1 : 0;
457  size = (n - 1) * spacing;
458  x = y = 0;
459  for (i = 0; i < n; i++) {
460  if ((pix1 = pixaGetPix(pixa1, i, L_CLONE)) == NULL) {
461  L_WARNING("missing pix at index %d\n", procName, i);
462  continue;
463  }
464 
465  if (scalefactor != 1.0)
466  pix2 = pixScale(pix1, scalefactor, scalefactor);
467  else
468  pix2 = pixClone(pix1);
469  if (border)
470  pix3 = pixAddBorder(pix2, border, bordval);
471  else
472  pix3 = pixClone(pix2);
473 
474  pixGetDimensions(pix3, &w, &h, NULL);
475  box = boxCreate(x, y, w, h);
476  if (direction == L_HORIZ) {
477  size += w;
478  x += w + spacing;
479  } else { /* vertical */
480  size += h;
481  y += h + spacing;
482  }
483  pixaAddPix(pixa2, pix3, L_INSERT);
484  pixaAddBox(pixa2, box, L_INSERT);
485  pixDestroy(&pix1);
486  pixDestroy(&pix2);
487  }
488  pixd = pixaDisplay(pixa2, 0, 0);
489 
490  if (pboxa)
491  *pboxa = pixaGetBoxa(pixa2, L_COPY);
492  pixaDestroy(&pixa1);
493  pixaDestroy(&pixa2);
494  return pixd;
495 }
496 
497 
521 PIX *
523  l_int32 cellw,
524  l_int32 cellh,
525  l_int32 *pncols,
526  BOXA **pboxa)
527 {
528 l_int32 n, nw, nh, w, h, d, wt, ht, res;
529 l_int32 index, i, j, hascmap;
530 BOX *box;
531 BOXA *boxa;
532 PIX *pix1, *pix2, *pixd;
533 PIXA *pixa1;
534 
535  PROCNAME("pixaDisplayOnLattice");
536 
537  if (pncols) *pncols = 0;
538  if (pboxa) *pboxa = NULL;
539  if (!pixa)
540  return (PIX *)ERROR_PTR("pixa not defined", procName, NULL);
541 
542  /* If any pix have colormaps, generate rgb */
543  if ((n = pixaGetCount(pixa)) == 0)
544  return (PIX *)ERROR_PTR("no components", procName, NULL);
545  pix1 = pixaGetPix(pixa, 0, L_CLONE);
546  res = pixGetXRes(pix1);
547  pixDestroy(&pix1);
548  pixaAnyColormaps(pixa, &hascmap);
549  if (hascmap) {
550  pixa1 = pixaCreate(n);
551  for (i = 0; i < n; i++) {
552  pix1 = pixaGetPix(pixa, i, L_CLONE);
553  pix2 = pixConvertTo32(pix1);
554  pixaAddPix(pixa1, pix2, L_INSERT);
555  pixDestroy(&pix1);
556  }
557  } else {
558  pixa1 = pixaCopy(pixa, L_CLONE);
559  }
560  boxa = boxaCreate(n);
561 
562  /* Have number of rows and columns approximately equal */
563  nw = (l_int32)sqrt((l_float64)n);
564  nh = (n + nw - 1) / nw;
565  w = cellw * nw;
566  h = cellh * nh;
567 
568  /* Use the first pix in pixa to determine the output depth. */
569  pixaGetPixDimensions(pixa1, 0, NULL, NULL, &d);
570  if ((pixd = pixCreate(w, h, d)) == NULL) {
571  pixaDestroy(&pixa1);
572  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
573  }
575  pixSetResolution(pixd, res, res);
576 
577  /* Tile the output */
578  index = 0;
579  for (i = 0; i < nh; i++) {
580  for (j = 0; j < nw && index < n; j++, index++) {
581  pix1 = pixaGetPix(pixa1, index, L_CLONE);
582  pixGetDimensions(pix1, &wt, &ht, NULL);
583  if (wt > cellw || ht > cellh) {
584  L_INFO("pix(%d) omitted; size %dx%x\n", procName, index,
585  wt, ht);
586  box = boxCreate(0, 0, 0, 0);
587  boxaAddBox(boxa, box, L_INSERT);
588  pixDestroy(&pix1);
589  continue;
590  }
591  pixRasterop(pixd, j * cellw, i * cellh, wt, ht,
592  PIX_SRC, pix1, 0, 0);
593  box = boxCreate(j * cellw, i * cellh, wt, ht);
594  boxaAddBox(boxa, box, L_INSERT);
595  pixDestroy(&pix1);
596  }
597  }
598 
599  if (pncols) *pncols = nw;
600  if (pboxa)
601  *pboxa = boxa;
602  else
603  boxaDestroy(&boxa);
604  pixaDestroy(&pixa1);
605  return pixd;
606 }
607 
608 
632 PIX *
634  l_int32 nx,
635  l_int32 ny,
636  l_int32 borderwidth,
637  l_uint32 bordercolor)
638 {
639 l_int32 w, h, d, wt, ht;
640 l_int32 i, j, k, x, y, n;
641 PIX *pix1, *pixd;
642 
643  PROCNAME("pixaDisplayUnsplit");
644 
645  if (!pixa)
646  return (PIX *)ERROR_PTR("pixa not defined", procName, NULL);
647  if (nx <= 0 || ny <= 0)
648  return (PIX *)ERROR_PTR("nx and ny must be > 0", procName, NULL);
649  if ((n = pixaGetCount(pixa)) == 0)
650  return (PIX *)ERROR_PTR("no components", procName, NULL);
651  if (n != nx * ny)
652  return (PIX *)ERROR_PTR("n != nx * ny", procName, NULL);
653  borderwidth = L_MAX(0, borderwidth);
654 
655  pixaGetPixDimensions(pixa, 0, &wt, &ht, &d);
656  w = nx * (wt + 2 * borderwidth);
657  h = ny * (ht + 2 * borderwidth);
658 
659  if ((pixd = pixCreate(w, h, d)) == NULL)
660  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
661  pix1 = pixaGetPix(pixa, 0, L_CLONE);
662  pixCopyColormap(pixd, pix1);
663  pixDestroy(&pix1);
664  if (borderwidth > 0)
665  pixSetAllArbitrary(pixd, bordercolor);
666 
667  y = borderwidth;
668  for (i = 0, k = 0; i < ny; i++) {
669  x = borderwidth;
670  for (j = 0; j < nx; j++, k++) {
671  pix1 = pixaGetPix(pixa, k, L_CLONE);
672  pixRasterop(pixd, x, y, wt, ht, PIX_SRC, pix1, 0, 0);
673  pixDestroy(&pix1);
674  x += wt + 2 * borderwidth;
675  }
676  y += ht + 2 * borderwidth;
677  }
678 
679  return pixd;
680 }
681 
682 
707 PIX *
709  l_int32 maxwidth,
710  l_int32 background,
711  l_int32 spacing)
712 {
713 l_int32 wmax, hmax, wd, hd, d, hascmap, res, same;
714 l_int32 i, j, n, ni, ncols, nrows;
715 l_int32 ystart, xstart, wt, ht;
716 PIX *pix1, *pix2, *pixd;
717 PIXA *pixa1;
718 
719  PROCNAME("pixaDisplayTiled");
720 
721  if (!pixa)
722  return (PIX *)ERROR_PTR("pixa not defined", procName, NULL);
723 
724  /* If any pix have colormaps, generate rgb */
725  if ((n = pixaGetCount(pixa)) == 0)
726  return (PIX *)ERROR_PTR("no components", procName, NULL);
727  pixaAnyColormaps(pixa, &hascmap);
728  if (hascmap) {
729  pixa1 = pixaCreate(n);
730  for (i = 0; i < n; i++) {
731  pix1 = pixaGetPix(pixa, i, L_CLONE);
732  pix2 = pixConvertTo32(pix1);
733  pixaAddPix(pixa1, pix2, L_INSERT);
734  pixDestroy(&pix1);
735  }
736  } else {
737  pixa1 = pixaCopy(pixa, L_CLONE);
738  }
739 
740  /* Find the max dimensions and depth subimages */
741  pixaGetDepthInfo(pixa1, &d, &same);
742  if (!same) {
743  pixaDestroy(&pixa1);
744  return (PIX *)ERROR_PTR("depths not equal", procName, NULL);
745  }
746  pixaSizeRange(pixa1, NULL, NULL, &wmax, &hmax);
747 
748  /* Get the number of rows and columns and the output image size */
749  spacing = L_MAX(spacing, 0);
750  ncols = (l_int32)((l_float32)(maxwidth - spacing) /
751  (l_float32)(wmax + spacing));
752  nrows = (n + ncols - 1) / ncols;
753  wd = wmax * ncols + spacing * (ncols + 1);
754  hd = hmax * nrows + spacing * (nrows + 1);
755  if ((pixd = pixCreate(wd, hd, d)) == NULL) {
756  pixaDestroy(&pixa1);
757  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
758  }
759 
760  /* Reset the background color if necessary */
761  if ((background == 1 && d == 1) || (background == 0 && d != 1))
762  pixSetAll(pixd);
763 
764  /* Blit the images to the dest */
765  for (i = 0, ni = 0; i < nrows; i++) {
766  ystart = spacing + i * (hmax + spacing);
767  for (j = 0; j < ncols && ni < n; j++, ni++) {
768  xstart = spacing + j * (wmax + spacing);
769  pix1 = pixaGetPix(pixa1, ni, L_CLONE);
770  if (ni == 0) res = pixGetXRes(pix1);
771  pixGetDimensions(pix1, &wt, &ht, NULL);
772  pixRasterop(pixd, xstart, ystart, wt, ht, PIX_SRC, pix1, 0, 0);
773  pixDestroy(&pix1);
774  }
775  }
776  pixSetResolution(pixd, res, res);
777 
778  pixaDestroy(&pixa1);
779  return pixd;
780 }
781 
782 
820 PIX *
822  l_int32 outdepth,
823  l_int32 maxwidth,
824  l_float32 scalefactor,
825  l_int32 background,
826  l_int32 spacing,
827  l_int32 border)
828 {
829 l_int32 h; /* cumulative height over all the rows */
830 l_int32 w; /* cumulative height in the current row */
831 l_int32 bordval, wtry, wt, ht;
832 l_int32 irow; /* index of current pix in current row */
833 l_int32 wmaxrow; /* width of the largest row */
834 l_int32 maxh; /* max height in row */
835 l_int32 i, j, index, n, x, y, nrows, ninrow, res;
836 size_t size;
837 l_uint8 *data;
838 BOXA *boxa;
839 NUMA *nainrow; /* number of pix in the row */
840 NUMA *namaxh; /* height of max pix in the row */
841 PIX *pix, *pixn, *pix1, *pixd;
842 PIXA *pixan;
843 
844  PROCNAME("pixaDisplayTiledInRows");
845 
846  if (!pixa)
847  return (PIX *)ERROR_PTR("pixa not defined", procName, NULL);
848  if (outdepth != 1 && outdepth != 8 && outdepth != 32)
849  return (PIX *)ERROR_PTR("outdepth not in {1, 8, 32}", procName, NULL);
850  if (border < 0)
851  border = 0;
852  if (scalefactor <= 0.0) scalefactor = 1.0;
853 
854  if ((n = pixaGetCount(pixa)) == 0)
855  return (PIX *)ERROR_PTR("no components", procName, NULL);
856 
857  /* Normalize depths, scale, remove colormaps; optionally add border */
858  pixan = pixaCreate(n);
859  bordval = (outdepth == 1) ? 1 : 0;
860  for (i = 0; i < n; i++) {
861  if ((pix = pixaGetPix(pixa, i, L_CLONE)) == NULL)
862  continue;
863 
864  if (outdepth == 1)
865  pixn = pixConvertTo1(pix, 128);
866  else if (outdepth == 8)
867  pixn = pixConvertTo8(pix, FALSE);
868  else /* outdepth == 32 */
869  pixn = pixConvertTo32(pix);
870  pixDestroy(&pix);
871 
872  if (scalefactor != 1.0)
873  pix1 = pixScale(pixn, scalefactor, scalefactor);
874  else
875  pix1 = pixClone(pixn);
876  if (border)
877  pixd = pixAddBorder(pix1, border, bordval);
878  else
879  pixd = pixClone(pix1);
880  pixDestroy(&pixn);
881  pixDestroy(&pix1);
882 
883  pixaAddPix(pixan, pixd, L_INSERT);
884  }
885  if (pixaGetCount(pixan) != n) {
886  n = pixaGetCount(pixan);
887  L_WARNING("only got %d components\n", procName, n);
888  if (n == 0) {
889  pixaDestroy(&pixan);
890  return (PIX *)ERROR_PTR("no components", procName, NULL);
891  }
892  }
893 
894  /* Compute parameters for layout */
895  nainrow = numaCreate(0);
896  namaxh = numaCreate(0);
897  wmaxrow = 0;
898  w = h = spacing;
899  maxh = 0; /* max height in row */
900  for (i = 0, irow = 0; i < n; i++, irow++) {
901  pixaGetPixDimensions(pixan, i, &wt, &ht, NULL);
902  wtry = w + wt + spacing;
903  if (wtry > maxwidth) { /* end the current row and start next one */
904  numaAddNumber(nainrow, irow);
905  numaAddNumber(namaxh, maxh);
906  wmaxrow = L_MAX(wmaxrow, w);
907  h += maxh + spacing;
908  irow = 0;
909  w = wt + 2 * spacing;
910  maxh = ht;
911  } else {
912  w = wtry;
913  maxh = L_MAX(maxh, ht);
914  }
915  }
916 
917  /* Enter the parameters for the last row */
918  numaAddNumber(nainrow, irow);
919  numaAddNumber(namaxh, maxh);
920  wmaxrow = L_MAX(wmaxrow, w);
921  h += maxh + spacing;
922 
923  if ((pixd = pixCreate(wmaxrow, h, outdepth)) == NULL) {
924  numaDestroy(&nainrow);
925  numaDestroy(&namaxh);
926  pixaDestroy(&pixan);
927  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
928  }
929 
930  /* Reset the background color if necessary */
931  if ((background == 1 && outdepth == 1) ||
932  (background == 0 && outdepth != 1))
933  pixSetAll(pixd);
934 
935  /* Blit the images to the dest, and save the boxa identifying
936  * the image regions that do not include the borders. */
937  nrows = numaGetCount(nainrow);
938  y = spacing;
939  boxa = boxaCreate(n);
940  for (i = 0, index = 0; i < nrows; i++) { /* over rows */
941  numaGetIValue(nainrow, i, &ninrow);
942  numaGetIValue(namaxh, i, &maxh);
943  x = spacing;
944  for (j = 0; j < ninrow; j++, index++) { /* over pix in row */
945  pix = pixaGetPix(pixan, index, L_CLONE);
946  if (index == 0) {
947  res = pixGetXRes(pix);
948  pixSetResolution(pixd, res, res);
949  }
950  pixGetDimensions(pix, &wt, &ht, NULL);
951  boxaAddBox(boxa, boxCreate(x + border, y + border,
952  wt - 2 * border, ht - 2 *border), L_INSERT);
953  pixRasterop(pixd, x, y, wt, ht, PIX_SRC, pix, 0, 0);
954  pixDestroy(&pix);
955  x += wt + spacing;
956  }
957  y += maxh + spacing;
958  }
959  boxaWriteMem(&data, &size, boxa);
960  pixSetText(pixd, (char *)data); /* data is ascii */
961  LEPT_FREE(data);
962  boxaDestroy(&boxa);
963 
964  numaDestroy(&nainrow);
965  numaDestroy(&namaxh);
966  pixaDestroy(&pixan);
967  return pixd;
968 }
969 
970 
1004 PIX *
1006  l_int32 nx,
1007  l_float32 scalefactor,
1008  l_int32 spacing,
1009  l_int32 border)
1010 {
1011 l_int32 i, j, index, n, x, y, nrows, wb, hb, w, h, maxd, maxh, bordval, res;
1012 size_t size;
1013 l_uint8 *data;
1014 BOX *box;
1015 BOXA *boxa;
1016 PIX *pix1, *pix2, *pix3, *pixd;
1017 PIXA *pixa1, *pixa2;
1018 
1019  PROCNAME("pixaDisplayTiledInColumns");
1020 
1021  if (!pixas)
1022  return (PIX *)ERROR_PTR("pixas not defined", procName, NULL);
1023  if (border < 0)
1024  border = 0;
1025  if (scalefactor <= 0.0) scalefactor = 1.0;
1026 
1027  if ((n = pixaGetCount(pixas)) == 0)
1028  return (PIX *)ERROR_PTR("no components", procName, NULL);
1029 
1030  /* Convert to same depth, if necessary */
1031  pixa1 = pixaConvertToSameDepth(pixas);
1032  pixaGetDepthInfo(pixa1, &maxd, NULL);
1033 
1034  /* Scale and optionally add border */
1035  pixa2 = pixaCreate(n);
1036  bordval = (maxd == 1) ? 1 : 0;
1037  for (i = 0; i < n; i++) {
1038  if ((pix1 = pixaGetPix(pixa1, i, L_CLONE)) == NULL)
1039  continue;
1040  if (scalefactor != 1.0)
1041  pix2 = pixScale(pix1, scalefactor, scalefactor);
1042  else
1043  pix2 = pixClone(pix1);
1044  if (border)
1045  pix3 = pixAddBorder(pix2, border, bordval);
1046  else
1047  pix3 = pixClone(pix2);
1048  if (i == 0) res = pixGetXRes(pix3);
1049  pixaAddPix(pixa2, pix3, L_INSERT);
1050  pixDestroy(&pix1);
1051  pixDestroy(&pix2);
1052  }
1053  pixaDestroy(&pixa1);
1054  if (pixaGetCount(pixa2) != n) {
1055  n = pixaGetCount(pixa2);
1056  L_WARNING("only got %d components\n", procName, n);
1057  if (n == 0) {
1058  pixaDestroy(&pixa2);
1059  return (PIX *)ERROR_PTR("no components", procName, NULL);
1060  }
1061  }
1062 
1063  /* Compute layout parameters and save as a boxa */
1064  boxa = boxaCreate(n);
1065  nrows = (n + nx - 1) / nx;
1066  y = spacing;
1067  for (i = 0, index = 0; i < nrows; i++) {
1068  x = spacing;
1069  maxh = 0;
1070  for (j = 0; j < nx && index < n; j++) {
1071  pixaGetPixDimensions(pixa2, index, &wb, &hb, NULL);
1072  box = boxCreate(x, y, wb, hb);
1073  boxaAddBox(boxa, box, L_INSERT);
1074  maxh = L_MAX(maxh, hb + spacing);
1075  x += wb + spacing;
1076  index++;
1077  }
1078  y += maxh;
1079  }
1080  pixaSetBoxa(pixa2, boxa, L_INSERT);
1081 
1082  /* Render the output pix */
1083  boxaGetExtent(boxa, &w, &h, NULL);
1084  pixd = pixaDisplay(pixa2, w + spacing, h + spacing);
1085  pixSetResolution(pixd, res, res);
1086 
1087  /* Save the boxa in the text field of the output pix */
1088  boxaWriteMem(&data, &size, boxa);
1089  pixSetText(pixd, (char *)data); /* data is ascii */
1090  LEPT_FREE(data);
1091 
1092  pixaDestroy(&pixa2);
1093  return pixd;
1094 }
1095 
1096 
1121 PIX *
1123  l_int32 outdepth,
1124  l_int32 tilewidth,
1125  l_int32 ncols,
1126  l_int32 background,
1127  l_int32 spacing,
1128  l_int32 border)
1129 {
1130 l_int32 x, y, w, h, wd, hd, d, res;
1131 l_int32 i, n, nrows, maxht, ninrow, irow, bordval;
1132 l_int32 *rowht;
1133 l_float32 scalefact;
1134 PIX *pix, *pixn, *pix1, *pixb, *pixd;
1135 PIXA *pixan;
1136 
1137  PROCNAME("pixaDisplayTiledAndScaled");
1138 
1139  if (!pixa)
1140  return (PIX *)ERROR_PTR("pixa not defined", procName, NULL);
1141  if (outdepth != 1 && outdepth != 8 && outdepth != 32)
1142  return (PIX *)ERROR_PTR("outdepth not in {1, 8, 32}", procName, NULL);
1143  if (border < 0 || border > tilewidth / 5)
1144  border = 0;
1145 
1146  if ((n = pixaGetCount(pixa)) == 0)
1147  return (PIX *)ERROR_PTR("no components", procName, NULL);
1148 
1149  /* Normalize scale and depth for each pix; optionally add border */
1150  pixan = pixaCreate(n);
1151  bordval = (outdepth == 1) ? 1 : 0;
1152  for (i = 0; i < n; i++) {
1153  if ((pix = pixaGetPix(pixa, i, L_CLONE)) == NULL)
1154  continue;
1155 
1156  pixGetDimensions(pix, &w, &h, &d);
1157  scalefact = (l_float32)(tilewidth - 2 * border) / (l_float32)w;
1158  if (d == 1 && outdepth > 1 && scalefact < 1.0)
1159  pix1 = pixScaleToGray(pix, scalefact);
1160  else
1161  pix1 = pixScale(pix, scalefact, scalefact);
1162 
1163  if (outdepth == 1)
1164  pixn = pixConvertTo1(pix1, 128);
1165  else if (outdepth == 8)
1166  pixn = pixConvertTo8(pix1, FALSE);
1167  else /* outdepth == 32 */
1168  pixn = pixConvertTo32(pix1);
1169  pixDestroy(&pix1);
1170 
1171  if (border)
1172  pixb = pixAddBorder(pixn, border, bordval);
1173  else
1174  pixb = pixClone(pixn);
1175 
1176  pixaAddPix(pixan, pixb, L_INSERT);
1177  pixDestroy(&pix);
1178  pixDestroy(&pixn);
1179  }
1180  if ((n = pixaGetCount(pixan)) == 0) { /* should not have changed! */
1181  pixaDestroy(&pixan);
1182  return (PIX *)ERROR_PTR("no components", procName, NULL);
1183  }
1184 
1185  /* Determine the size of each row and of pixd */
1186  wd = tilewidth * ncols + spacing * (ncols + 1);
1187  nrows = (n + ncols - 1) / ncols;
1188  if ((rowht = (l_int32 *)LEPT_CALLOC(nrows, sizeof(l_int32))) == NULL) {
1189  pixaDestroy(&pixan);
1190  return (PIX *)ERROR_PTR("rowht array not made", procName, NULL);
1191  }
1192  maxht = 0;
1193  ninrow = 0;
1194  irow = 0;
1195  for (i = 0; i < n; i++) {
1196  pix = pixaGetPix(pixan, i, L_CLONE);
1197  ninrow++;
1198  pixGetDimensions(pix, &w, &h, NULL);
1199  maxht = L_MAX(h, maxht);
1200  if (ninrow == ncols) {
1201  rowht[irow] = maxht;
1202  maxht = ninrow = 0; /* reset */
1203  irow++;
1204  }
1205  pixDestroy(&pix);
1206  }
1207  if (ninrow > 0) { /* last fencepost */
1208  rowht[irow] = maxht;
1209  irow++; /* total number of rows */
1210  }
1211  nrows = irow;
1212  hd = spacing * (nrows + 1);
1213  for (i = 0; i < nrows; i++)
1214  hd += rowht[i];
1215 
1216  pixd = pixCreate(wd, hd, outdepth);
1217  if ((background == 1 && outdepth == 1) ||
1218  (background == 0 && outdepth != 1))
1219  pixSetAll(pixd);
1220 
1221  /* Now blit images to pixd */
1222  x = y = spacing;
1223  irow = 0;
1224  for (i = 0; i < n; i++) {
1225  pix = pixaGetPix(pixan, i, L_CLONE);
1226  if (i == 0) {
1227  res = pixGetXRes(pix);
1228  pixSetResolution(pixd, res, res);
1229  }
1230  pixGetDimensions(pix, &w, &h, NULL);
1231  if (i && ((i % ncols) == 0)) { /* start new row */
1232  x = spacing;
1233  y += spacing + rowht[irow];
1234  irow++;
1235  }
1236  pixRasterop(pixd, x, y, w, h, PIX_SRC, pix, 0, 0);
1237  x += tilewidth + spacing;
1238  pixDestroy(&pix);
1239  }
1240 
1241  pixaDestroy(&pixan);
1242  LEPT_FREE(rowht);
1243  return pixd;
1244 }
1245 
1246 
1274 PIX *
1276  l_int32 maxwidth,
1277  l_float32 scalefactor,
1278  l_int32 spacing,
1279  l_int32 border,
1280  l_int32 fontsize,
1281  l_uint32 textcolor)
1282 {
1283 char buf[128];
1284 char *textstr;
1285 l_int32 i, n, maxw;
1286 L_BMF *bmf;
1287 PIX *pix1, *pix2, *pix3, *pix4, *pixd;
1288 PIXA *pixad;
1289 
1290  PROCNAME("pixaDisplayTiledWithText");
1291 
1292  if (!pixa)
1293  return (PIX *)ERROR_PTR("pixa not defined", procName, NULL);
1294  if ((n = pixaGetCount(pixa)) == 0)
1295  return (PIX *)ERROR_PTR("no components", procName, NULL);
1296  if (maxwidth <= 0)
1297  return (PIX *)ERROR_PTR("invalid maxwidth", procName, NULL);
1298  if (border < 0)
1299  border = 0;
1300  if (scalefactor <= 0.0) {
1301  L_WARNING("invalid scalefactor; setting to 1.0\n", procName);
1302  scalefactor = 1.0;
1303  }
1304  if (fontsize < 4 || fontsize > 20 || (fontsize & 1)) {
1305  l_int32 fsize = L_MAX(L_MIN(fontsize, 20), 4);
1306  if (fsize & 1) fsize--;
1307  L_WARNING("changed fontsize from %d to %d\n", procName,
1308  fontsize, fsize);
1309  fontsize = fsize;
1310  }
1311 
1312  /* Be sure the width can accommodate a single column of images */
1313  pixaSizeRange(pixa, NULL, NULL, &maxw, NULL);
1314  maxwidth = L_MAX(maxwidth, scalefactor * (maxw + 2 * spacing + 2 * border));
1315 
1316  bmf = bmfCreate(NULL, fontsize);
1317  pixad = pixaCreate(n);
1318  for (i = 0; i < n; i++) {
1319  pix1 = pixaGetPix(pixa, i, L_CLONE);
1320  pix2 = pixConvertTo32(pix1);
1321  pix3 = pixAddBorderGeneral(pix2, spacing, spacing, spacing,
1322  spacing, 0xffffff00);
1323  textstr = pixGetText(pix1);
1324  if (textstr && strlen(textstr) > 0) {
1325  snprintf(buf, sizeof(buf), "%s", textstr);
1326  pix4 = pixAddSingleTextblock(pix3, bmf, buf, textcolor,
1327  L_ADD_BELOW, NULL);
1328  } else {
1329  pix4 = pixClone(pix3);
1330  }
1331  pixaAddPix(pixad, pix4, L_INSERT);
1332  pixDestroy(&pix1);
1333  pixDestroy(&pix2);
1334  pixDestroy(&pix3);
1335  }
1336  bmfDestroy(&bmf);
1337 
1338  pixd = pixaDisplayTiledInRows(pixad, 32, maxwidth, scalefactor,
1339  0, 10, border);
1340  pixaDestroy(&pixad);
1341  return pixd;
1342 }
1343 
1344 
1373 PIX *
1375  NUMA *na,
1376  l_int32 width,
1377  l_int32 spacing,
1378  l_int32 border,
1379  l_int32 fontsize,
1380  l_uint32 textcolor)
1381 {
1382 char buf[128];
1383 char *textstr;
1384 l_int32 i, n, x, y, w, h, yval, index;
1385 l_float32 maxindex;
1386 L_BMF *bmf;
1387 BOX *box;
1388 NUMA *nay; /* top of the next pix to add in that column */
1389 PIX *pix1, *pix2, *pix3, *pix4, *pix5, *pixd;
1390 PIXA *pixad;
1391 
1392  PROCNAME("pixaDisplayTiledByIndex");
1393 
1394  if (!pixa)
1395  return (PIX *)ERROR_PTR("pixa not defined", procName, NULL);
1396  if (!na)
1397  return (PIX *)ERROR_PTR("na not defined", procName, NULL);
1398  if ((n = pixaGetCount(pixa)) == 0)
1399  return (PIX *)ERROR_PTR("no pixa components", procName, NULL);
1400  if (n != numaGetCount(na))
1401  return (PIX *)ERROR_PTR("pixa and na counts differ", procName, NULL);
1402  if (width <= 0)
1403  return (PIX *)ERROR_PTR("invalid width", procName, NULL);
1404  if (width < 20)
1405  L_WARNING("very small width: %d\n", procName, width);
1406  if (border < 0)
1407  border = 0;
1408  if (fontsize < 4 || fontsize > 20 || (fontsize & 1)) {
1409  l_int32 fsize = L_MAX(L_MIN(fontsize, 20), 4);
1410  if (fsize & 1) fsize--;
1411  L_WARNING("changed fontsize from %d to %d\n", procName,
1412  fontsize, fsize);
1413  fontsize = fsize;
1414  }
1415 
1416  /* The pix will be rendered in the order they occupy in pixa. */
1417  bmf = bmfCreate(NULL, fontsize);
1418  pixad = pixaCreate(n);
1419  numaGetMax(na, &maxindex, NULL);
1420  nay = numaMakeConstant(spacing, lept_roundftoi(maxindex) + 1);
1421  for (i = 0; i < n; i++) {
1422  numaGetIValue(na, i, &index);
1423  numaGetIValue(nay, index, &yval);
1424  pix1 = pixaGetPix(pixa, i, L_CLONE);
1425  pix2 = pixConvertTo32(pix1);
1426  pix3 = pixScaleToSize(pix2, width, 0);
1427  pix4 = pixAddBorderGeneral(pix3, border, border, border, border, 0);
1428  textstr = pixGetText(pix1);
1429  if (textstr && strlen(textstr) > 0) {
1430  snprintf(buf, sizeof(buf), "%s", textstr);
1431  pix5 = pixAddTextlines(pix4, bmf, textstr, textcolor, L_ADD_BELOW);
1432  } else {
1433  pix5 = pixClone(pix4);
1434  }
1435  pixaAddPix(pixad, pix5, L_INSERT);
1436  x = spacing + border + index * (2 * border + width + spacing);
1437  y = yval;
1438  pixGetDimensions(pix5, &w, &h, NULL);
1439  yval += h + spacing;
1440  numaSetValue(nay, index, yval);
1441  box = boxCreate(x, y, w, h);
1442  pixaAddBox(pixad, box, L_INSERT);
1443  pixDestroy(&pix1);
1444  pixDestroy(&pix2);
1445  pixDestroy(&pix3);
1446  pixDestroy(&pix4);
1447  }
1448  numaDestroy(&nay);
1449  bmfDestroy(&bmf);
1450 
1451  pixd = pixaDisplay(pixad, 0, 0);
1452  pixaDestroy(&pixad);
1453  return pixd;
1454 }
1455 
1456 
1457 
1458 /*---------------------------------------------------------------------*
1459  * Pixaa Display *
1460  *---------------------------------------------------------------------*/
1476 PIX *
1478  l_int32 w,
1479  l_int32 h)
1480 {
1481 l_int32 i, j, n, nbox, na, d, wmax, hmax, x, y, xb, yb, wb, hb;
1482 BOXA *boxa1; /* top-level boxa */
1483 BOXA *boxa;
1484 PIX *pix1, *pixd;
1485 PIXA *pixa;
1486 
1487  PROCNAME("pixaaDisplay");
1488 
1489  if (!paa)
1490  return (PIX *)ERROR_PTR("paa not defined", procName, NULL);
1491 
1492  n = pixaaGetCount(paa, NULL);
1493  if (n == 0)
1494  return (PIX *)ERROR_PTR("no components", procName, NULL);
1495 
1496  /* If w and h not input, determine the minimum size required
1497  * to contain the origin and all c.c. */
1498  boxa1 = pixaaGetBoxa(paa, L_CLONE);
1499  nbox = boxaGetCount(boxa1);
1500  if (w == 0 || h == 0) {
1501  if (nbox == n) {
1502  boxaGetExtent(boxa1, &w, &h, NULL);
1503  } else { /* have to use the lower-level boxa for each pixa */
1504  wmax = hmax = 0;
1505  for (i = 0; i < n; i++) {
1506  pixa = pixaaGetPixa(paa, i, L_CLONE);
1507  boxa = pixaGetBoxa(pixa, L_CLONE);
1508  boxaGetExtent(boxa, &w, &h, NULL);
1509  wmax = L_MAX(wmax, w);
1510  hmax = L_MAX(hmax, h);
1511  pixaDestroy(&pixa);
1512  boxaDestroy(&boxa);
1513  }
1514  w = wmax;
1515  h = hmax;
1516  }
1517  }
1518 
1519  /* Get depth from first pix */
1520  pixa = pixaaGetPixa(paa, 0, L_CLONE);
1521  pix1 = pixaGetPix(pixa, 0, L_CLONE);
1522  d = pixGetDepth(pix1);
1523  pixaDestroy(&pixa);
1524  pixDestroy(&pix1);
1525 
1526  if ((pixd = pixCreate(w, h, d)) == NULL) {
1527  boxaDestroy(&boxa1);
1528  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
1529  }
1530 
1531  x = y = 0;
1532  for (i = 0; i < n; i++) {
1533  pixa = pixaaGetPixa(paa, i, L_CLONE);
1534  if (nbox == n)
1535  boxaGetBoxGeometry(boxa1, i, &x, &y, NULL, NULL);
1536  na = pixaGetCount(pixa);
1537  for (j = 0; j < na; j++) {
1538  pixaGetBoxGeometry(pixa, j, &xb, &yb, &wb, &hb);
1539  pix1 = pixaGetPix(pixa, j, L_CLONE);
1540  pixRasterop(pixd, x + xb, y + yb, wb, hb, PIX_PAINT, pix1, 0, 0);
1541  pixDestroy(&pix1);
1542  }
1543  pixaDestroy(&pixa);
1544  }
1545  boxaDestroy(&boxa1);
1546 
1547  return pixd;
1548 }
1549 
1550 
1570 PIX *
1572  l_int32 xspace,
1573  l_int32 yspace,
1574  l_int32 maxw)
1575 {
1576 l_int32 i, j, npixa, npix, same, use_maxw, x, y, w, h, hindex;
1577 l_int32 maxwidth, maxd, width, lmaxh, lmaxw;
1578 l_int32 *harray;
1579 NUMA *nah;
1580 PIX *pix, *pix1, *pixd;
1581 PIXA *pixa;
1582 
1583  PROCNAME("pixaaDisplayByPixa");
1584 
1585  if (!paa)
1586  return (PIX *)ERROR_PTR("paa not defined", procName, NULL);
1587 
1588  if ((npixa = pixaaGetCount(paa, NULL)) == 0)
1589  return (PIX *)ERROR_PTR("no components", procName, NULL);
1590  pixaaVerifyDepth(paa, &same, &maxd);
1591  if (!same && maxd < 8)
1592  return (PIX *)ERROR_PTR("depths differ; max < 8", procName, NULL);
1593 
1594  /* Be sure the widest box fits in the output pix */
1595  pixaaSizeRange(paa, NULL, NULL, &maxwidth, NULL);
1596  if (maxwidth > maxw) {
1597  L_WARNING("maxwidth > maxw; using maxwidth\n", procName);
1598  maxw = maxwidth;
1599  }
1600 
1601  /* Get size of output pix. The width is the minimum of the
1602  * maxw and the largest pixa line width. The height is whatever
1603  * it needs to be to accommodate all pixa. */
1604  lmaxw = 0; /* widest line found */
1605  use_maxw = FALSE;
1606  nah = numaCreate(0); /* store height of each line */
1607  y = yspace;
1608  for (i = 0; i < npixa; i++) {
1609  pixa = pixaaGetPixa(paa, i, L_CLONE);
1610  npix = pixaGetCount(pixa);
1611  if (npix == 0) {
1612  pixaDestroy(&pixa);
1613  continue;
1614  }
1615  x = xspace;
1616  lmaxh = 0; /* max height found in the line */
1617  for (j = 0; j < npix; j++) {
1618  pix = pixaGetPix(pixa, j, L_CLONE);
1619  pixGetDimensions(pix, &w, &h, NULL);
1620  if (x + w >= maxw) { /* start new line */
1621  x = xspace;
1622  y += lmaxh + yspace;
1623  numaAddNumber(nah, lmaxh);
1624  lmaxh = 0;
1625  use_maxw = TRUE;
1626  }
1627  x += w + xspace;
1628  lmaxh = L_MAX(h, lmaxh);
1629  lmaxw = L_MAX(lmaxw, x);
1630  pixDestroy(&pix);
1631  }
1632  y += lmaxh + yspace;
1633  numaAddNumber(nah, lmaxh);
1634  pixaDestroy(&pixa);
1635  }
1636  width = (use_maxw) ? maxw : lmaxw;
1637 
1638  if ((pixd = pixCreate(width, y, maxd)) == NULL) {
1639  numaDestroy(&nah);
1640  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
1641  }
1642 
1643  /* Now layout the pix by pixa */
1644  y = yspace;
1645  harray = numaGetIArray(nah);
1646  hindex = 0;
1647  for (i = 0; i < npixa; i++) {
1648  x = xspace;
1649  pixa = pixaaGetPixa(paa, i, L_CLONE);
1650  npix = pixaGetCount(pixa);
1651  if (npix == 0) {
1652  pixaDestroy(&pixa);
1653  continue;
1654  }
1655  for (j = 0; j < npix; j++) {
1656  pix = pixaGetPix(pixa, j, L_CLONE);
1657  if (pixGetDepth(pix) != maxd) {
1658  if (maxd == 8)
1659  pix1 = pixConvertTo8(pix, 0);
1660  else /* 32 bpp */
1661  pix1 = pixConvertTo32(pix);
1662  } else {
1663  pix1 = pixClone(pix);
1664  }
1665  pixGetDimensions(pix1, &w, &h, NULL);
1666  if (x + w >= maxw) { /* start new line */
1667  x = xspace;
1668  y += harray[hindex++] + yspace;
1669  }
1670  pixRasterop(pixd, x, y, w, h, PIX_PAINT, pix1, 0, 0);
1671  pixDestroy(&pix);
1672  pixDestroy(&pix1);
1673  x += w + xspace;
1674  }
1675  y += harray[hindex++] + yspace;
1676  pixaDestroy(&pixa);
1677  }
1678  LEPT_FREE(harray);
1679 
1680  numaDestroy(&nah);
1681  return pixd;
1682 }
1683 
1684 
1707 PIXA *
1709  l_int32 outdepth,
1710  l_int32 tilewidth,
1711  l_int32 ncols,
1712  l_int32 background,
1713  l_int32 spacing,
1714  l_int32 border)
1715 {
1716 l_int32 i, n;
1717 PIX *pix;
1718 PIXA *pixa, *pixad;
1719 
1720  PROCNAME("pixaaDisplayTiledAndScaled");
1721 
1722  if (!paa)
1723  return (PIXA *)ERROR_PTR("paa not defined", procName, NULL);
1724  if (outdepth != 1 && outdepth != 8 && outdepth != 32)
1725  return (PIXA *)ERROR_PTR("outdepth not in {1, 8, 32}", procName, NULL);
1726  if (border < 0 || border > tilewidth / 5)
1727  border = 0;
1728 
1729  if ((n = pixaaGetCount(paa, NULL)) == 0)
1730  return (PIXA *)ERROR_PTR("no components", procName, NULL);
1731 
1732  pixad = pixaCreate(n);
1733  for (i = 0; i < n; i++) {
1734  pixa = pixaaGetPixa(paa, i, L_CLONE);
1735  pix = pixaDisplayTiledAndScaled(pixa, outdepth, tilewidth, ncols,
1736  background, spacing, border);
1737  pixaAddPix(pixad, pix, L_INSERT);
1738  pixaDestroy(&pixa);
1739  }
1740 
1741  return pixad;
1742 }
1743 
1744 
1745 /*---------------------------------------------------------------------*
1746  * Conversion of all pix to specified type (e.g., depth) *
1747  *---------------------------------------------------------------------*/
1755 PIXA *
1757  l_int32 thresh)
1758 {
1759 l_int32 i, n;
1760 BOXA *boxa;
1761 PIX *pix1, *pix2;
1762 PIXA *pixad;
1763 
1764  PROCNAME("pixaConvertTo1");
1765 
1766  if (!pixas)
1767  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1768 
1769  n = pixaGetCount(pixas);
1770  pixad = pixaCreate(n);
1771  for (i = 0; i < n; i++) {
1772  pix1 = pixaGetPix(pixas, i, L_CLONE);
1773  pix2 = pixConvertTo1(pix1, thresh);
1774  pixaAddPix(pixad, pix2, L_INSERT);
1775  pixDestroy(&pix1);
1776  }
1777 
1778  boxa = pixaGetBoxa(pixas, L_COPY);
1779  pixaSetBoxa(pixad, boxa, L_INSERT);
1780  return pixad;
1781 }
1782 
1783 
1796 PIXA *
1798  l_int32 cmapflag)
1799 {
1800 l_int32 i, n;
1801 BOXA *boxa;
1802 PIX *pix1, *pix2;
1803 PIXA *pixad;
1804 
1805  PROCNAME("pixaConvertTo8");
1806 
1807  if (!pixas)
1808  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1809 
1810  n = pixaGetCount(pixas);
1811  pixad = pixaCreate(n);
1812  for (i = 0; i < n; i++) {
1813  pix1 = pixaGetPix(pixas, i, L_CLONE);
1814  pix2 = pixConvertTo8(pix1, cmapflag);
1815  pixaAddPix(pixad, pix2, L_INSERT);
1816  pixDestroy(&pix1);
1817  }
1818 
1819  boxa = pixaGetBoxa(pixas, L_COPY);
1820  pixaSetBoxa(pixad, boxa, L_INSERT);
1821  return pixad;
1822 }
1823 
1824 
1837 PIXA *
1839  l_int32 dither)
1840 {
1841 l_int32 i, n;
1842 BOXA *boxa;
1843 PIX *pix1, *pix2;
1844 PIXA *pixad;
1845 
1846  PROCNAME("pixaConvertTo8Colormap");
1847 
1848  if (!pixas)
1849  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1850 
1851  n = pixaGetCount(pixas);
1852  pixad = pixaCreate(n);
1853  for (i = 0; i < n; i++) {
1854  pix1 = pixaGetPix(pixas, i, L_CLONE);
1855  pix2 = pixConvertTo8Colormap(pix1, dither);
1856  pixaAddPix(pixad, pix2, L_INSERT);
1857  pixDestroy(&pix1);
1858  }
1859 
1860  boxa = pixaGetBoxa(pixas, L_COPY);
1861  pixaSetBoxa(pixad, boxa, L_INSERT);
1862  return pixad;
1863 }
1864 
1865 
1879 PIXA *
1881 {
1882 l_int32 i, n;
1883 BOXA *boxa;
1884 PIX *pix1, *pix2;
1885 PIXA *pixad;
1886 
1887  PROCNAME("pixaConvertTo32");
1888 
1889  if (!pixas)
1890  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1891 
1892  n = pixaGetCount(pixas);
1893  pixad = pixaCreate(n);
1894  for (i = 0; i < n; i++) {
1895  pix1 = pixaGetPix(pixas, i, L_CLONE);
1896  pix2 = pixConvertTo32(pix1);
1897  pixaAddPix(pixad, pix2, L_INSERT);
1898  pixDestroy(&pix1);
1899  }
1900 
1901  boxa = pixaGetBoxa(pixas, L_COPY);
1902  pixaSetBoxa(pixad, boxa, L_INSERT);
1903  return pixad;
1904 }
1905 
1906 
1907 /*---------------------------------------------------------------------*
1908  * Pixa constrained selection *
1909  *---------------------------------------------------------------------*/
1932 PIXA *
1934  l_int32 first,
1935  l_int32 last,
1936  l_int32 nmax,
1937  l_int32 use_pairs,
1938  l_int32 copyflag)
1939 {
1940 l_int32 i, n, nselect, index;
1941 NUMA *na;
1942 PIX *pix1;
1943 PIXA *pixad;
1944 
1945  PROCNAME("pixaConstrainedSelect");
1946 
1947  if (!pixas)
1948  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
1949  n = pixaGetCount(pixas);
1950  first = L_MAX(0, first);
1951  last = (last < 0) ? n - 1 : L_MIN(n - 1, last);
1952  if (last < first)
1953  return (PIXA *)ERROR_PTR("last < first!", procName, NULL);
1954  if (nmax < 1)
1955  return (PIXA *)ERROR_PTR("nmax < 1!", procName, NULL);
1956 
1957  na = genConstrainedNumaInRange(first, last, nmax, use_pairs);
1958  nselect = numaGetCount(na);
1959  pixad = pixaCreate(nselect);
1960  for (i = 0; i < nselect; i++) {
1961  numaGetIValue(na, i, &index);
1962  pix1 = pixaGetPix(pixas, index, copyflag);
1963  pixaAddPix(pixad, pix1, L_INSERT);
1964  }
1965  numaDestroy(&na);
1966  return pixad;
1967 }
1968 
1969 
2000 l_int32
2002  l_int32 first,
2003  l_int32 last,
2004  l_int32 res,
2005  l_float32 scalefactor,
2006  l_int32 type,
2007  l_int32 quality,
2008  l_uint32 color,
2009  l_int32 fontsize,
2010  const char *fileout)
2011 {
2012 l_int32 n;
2013 L_BMF *bmf;
2014 NUMA *na;
2015 PIXA *pixa1, *pixa2;
2016 
2017  PROCNAME("pixaSelectToPdf");
2018 
2019  if (!pixas)
2020  return ERROR_INT("pixas not defined", procName, 1);
2021  if (type < 0 || type > L_FLATE_ENCODE) {
2022  L_WARNING("invalid compression type; using default\n", procName);
2023  type = 0;
2024  }
2025  if (!fileout)
2026  return ERROR_INT("fileout not defined", procName, 1);
2027 
2028  /* Select from given range */
2029  n = pixaGetCount(pixas);
2030  first = L_MAX(0, first);
2031  last = (last < 0) ? n - 1 : L_MIN(n - 1, last);
2032  if (first > last) {
2033  L_ERROR("first = %d > last = %d\n", procName, first, last);
2034  return 1;
2035  }
2036  pixa1 = pixaSelectRange(pixas, first, last, L_CLONE);
2037 
2038  /* Optionally add index numbers */
2039  bmf = (fontsize <= 0) ? NULL : bmfCreate(NULL, fontsize);
2040  if (bmf) {
2041  na = numaMakeSequence(first, 1.0, last - first + 1);
2042  pixa2 = pixaAddTextNumber(pixa1, bmf, na, color, L_ADD_LEFT);
2043  numaDestroy(&na);
2044  } else {
2045  pixa2 = pixaCopy(pixa1, L_CLONE);
2046  }
2047  pixaDestroy(&pixa1);
2048  bmfDestroy(&bmf);
2049 
2050  pixaConvertToPdf(pixa2, res, scalefactor, type, quality, NULL, fileout);
2051  pixaDestroy(&pixa2);
2052  return 0;
2053 }
2054 
2055 
2056 /*---------------------------------------------------------------------*
2057  * Pixa display into multiple tiles *
2058  *---------------------------------------------------------------------*/
2080 PIXA *
2082  l_int32 nx,
2083  l_int32 ny,
2084  l_int32 maxw,
2085  l_int32 maxh,
2086  l_float32 scalefactor,
2087  l_int32 spacing,
2088  l_int32 border)
2089 {
2090 l_int32 n, i, j, ntile, nout, index;
2091 PIX *pix1, *pix2;
2092 PIXA *pixa1, *pixa2, *pixad;
2093 
2094  PROCNAME("pixaDisplayMultiTiled");
2095 
2096  if (!pixas)
2097  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
2098  if (nx < 1 || ny < 1 || nx > 50 || ny > 50)
2099  return (PIXA *)ERROR_PTR("invalid tiling factor(s)", procName, NULL);
2100  if ((n = pixaGetCount(pixas)) == 0)
2101  return (PIXA *)ERROR_PTR("pixas is empty", procName, NULL);
2102 
2103  /* Filter out large ones if requested */
2104  if (maxw == 0 && maxh == 0) {
2105  pixa1 = pixaCopy(pixas, L_CLONE);
2106  } else {
2107  maxw = (maxw == 0) ? 1000000 : maxw;
2108  maxh = (maxh == 0) ? 1000000 : maxh;
2109  pixa1 = pixaSelectBySize(pixas, maxw, maxh, L_SELECT_IF_BOTH,
2110  L_SELECT_IF_LTE, NULL);
2111  n = pixaGetCount(pixa1);
2112  }
2113 
2114  ntile = nx * ny;
2115  nout = L_MAX(1, (n + ntile - 1) / ntile);
2116  pixad = pixaCreate(nout);
2117  for (i = 0, index = 0; i < nout; i++) { /* over tiles */
2118  pixa2 = pixaCreate(ntile);
2119  for (j = 0; j < ntile && index < n; j++, index++) {
2120  pix1 = pixaGetPix(pixa1, index, L_COPY);
2121  pixaAddPix(pixa2, pix1, L_INSERT);
2122  }
2123  pix2 = pixaDisplayTiledInColumns(pixa2, nx, scalefactor, spacing,
2124  border);
2125  pixaAddPix(pixad, pix2, L_INSERT);
2126  pixaDestroy(&pixa2);
2127  }
2128  pixaDestroy(&pixa1);
2129 
2130  return pixad;
2131 }
2132 
2133 
2134 /*---------------------------------------------------------------------*
2135  * Split pixa into files *
2136  *---------------------------------------------------------------------*/
2159 l_int32
2161  l_int32 nsplit,
2162  l_float32 scale,
2163  l_int32 outwidth,
2164  l_int32 write_pixa,
2165  l_int32 write_pix,
2166  l_int32 write_pdf)
2167 {
2168 char buf[64];
2169 l_int32 i, j, index, n, nt;
2170 PIX *pix1, *pix2;
2171 PIXA *pixa1;
2172 
2173  PROCNAME("pixaSplitIntoFiles");
2174 
2175  if (!pixas)
2176  return ERROR_INT("pixas not defined", procName, 1);
2177  if (nsplit <= 1)
2178  return ERROR_INT("nsplit must be >= 2", procName, 1);
2179  if ((nt = pixaGetCount(pixas)) == 0)
2180  return ERROR_INT("pixas is empty", procName, 1);
2181  if (!write_pixa && !write_pix && !write_pdf)
2182  return ERROR_INT("no output is requested", procName, 1);
2183 
2184  lept_mkdir("lept/split");
2185  n = (nt + nsplit - 1) / nsplit;
2186  fprintf(stderr, "nt = %d, n = %d, nsplit = %d\n", nt, n, nsplit);
2187  for (i = 0, index = 0; i < nsplit; i++) {
2188  pixa1 = pixaCreate(n);
2189  for (j = 0; j < n && index < nt; j++, index++) {
2190  pix1 = pixaGetPix(pixas, index, L_CLONE);
2191  pix2 = pixScale(pix1, scale, scale);
2192  pixaAddPix(pixa1, pix2, L_INSERT);
2193  pixDestroy(&pix1);
2194  }
2195  if (write_pixa) {
2196  snprintf(buf, sizeof(buf), "/tmp/lept/split/split%d.pa", i + 1);
2197  pixaWrite(buf, pixa1);
2198  }
2199  if (write_pix) {
2200  snprintf(buf, sizeof(buf), "/tmp/lept/split/split%d.tif", i + 1);
2201  pix1 = pixaDisplayTiledInRows(pixa1, 1, outwidth, 1.0, 0, 20, 2);
2202  pixWrite(buf, pix1, IFF_TIFF_G4);
2203  pixDestroy(&pix1);
2204  }
2205  if (write_pdf) {
2206  snprintf(buf, sizeof(buf), "/tmp/lept/split/split%d.pdf", i + 1);
2207  pixaConvertToPdf(pixa1, 0, 1.0, L_G4_ENCODE, 0, buf, buf);
2208  }
2209  pixaDestroy(&pixa1);
2210  }
2211 
2212  return 0;
2213 }
2214 
2215 
2216 /*---------------------------------------------------------------------*
2217  * Tile N-Up *
2218  *---------------------------------------------------------------------*/
2248 l_int32
2249 convertToNUpFiles(const char *dir,
2250  const char *substr,
2251  l_int32 nx,
2252  l_int32 ny,
2253  l_int32 tw,
2254  l_int32 spacing,
2255  l_int32 border,
2256  l_int32 fontsize,
2257  const char *outdir)
2258 {
2259 l_int32 d, format;
2260 char rootpath[256];
2261 PIXA *pixa;
2262 
2263  PROCNAME("convertToNUpFiles");
2264 
2265  if (!dir)
2266  return ERROR_INT("dir not defined", procName, 1);
2267  if (nx < 1 || ny < 1 || nx > 50 || ny > 50)
2268  return ERROR_INT("invalid tiling N-factor", procName, 1);
2269  if (fontsize < 0 || fontsize > 20 || fontsize & 1 || fontsize == 2)
2270  return ERROR_INT("invalid fontsize", procName, 1);
2271  if (!outdir)
2272  return ERROR_INT("outdir not defined", procName, 1);
2273 
2274  pixa = convertToNUpPixa(dir, substr, nx, ny, tw, spacing, border,
2275  fontsize);
2276  if (!pixa)
2277  return ERROR_INT("pixa not made", procName, 1);
2278 
2279  lept_rmdir(outdir);
2280  lept_mkdir(outdir);
2281  pixaGetRenderingDepth(pixa, &d);
2282  format = (d == 1) ? IFF_TIFF_G4 : IFF_JFIF_JPEG;
2283  makeTempDirname(rootpath, 256, outdir);
2284  modifyTrailingSlash(rootpath, 256, L_ADD_TRAIL_SLASH);
2285  pixaWriteFiles(rootpath, pixa, format);
2286  pixaDestroy(&pixa);
2287  return 0;
2288 }
2289 
2290 
2310 PIXA *
2311 convertToNUpPixa(const char *dir,
2312  const char *substr,
2313  l_int32 nx,
2314  l_int32 ny,
2315  l_int32 tw,
2316  l_int32 spacing,
2317  l_int32 border,
2318  l_int32 fontsize)
2319 {
2320 l_int32 i, n;
2321 char *fname, *tail;
2322 PIXA *pixa1, *pixa2;
2323 SARRAY *sa1, *sa2;
2324 
2325  PROCNAME("convertToNUpPixa");
2326 
2327  if (!dir)
2328  return (PIXA *)ERROR_PTR("dir not defined", procName, NULL);
2329  if (nx < 1 || ny < 1 || nx > 50 || ny > 50)
2330  return (PIXA *)ERROR_PTR("invalid tiling N-factor", procName, NULL);
2331  if (tw < 20)
2332  return (PIXA *)ERROR_PTR("tw must be >= 20", procName, NULL);
2333  if (fontsize < 0 || fontsize > 20 || fontsize & 1 || fontsize == 2)
2334  return (PIXA *)ERROR_PTR("invalid fontsize", procName, NULL);
2335 
2336  sa1 = getSortedPathnamesInDirectory(dir, substr, 0, 0);
2337  pixa1 = pixaReadFilesSA(sa1);
2338  n = sarrayGetCount(sa1);
2339  sa2 = sarrayCreate(n);
2340  for (i = 0; i < n; i++) {
2341  fname = sarrayGetString(sa1, i, L_NOCOPY);
2342  splitPathAtDirectory(fname, NULL, &tail);
2343  sarrayAddString(sa2, tail, L_INSERT);
2344  }
2345  sarrayDestroy(&sa1);
2346  pixa2 = pixaConvertToNUpPixa(pixa1, sa2, nx, ny, tw, spacing,
2347  border, fontsize);
2348  pixaDestroy(&pixa1);
2349  sarrayDestroy(&sa2);
2350  return pixa2;
2351 }
2352 
2353 
2376 PIXA *
2378  SARRAY *sa,
2379  l_int32 nx,
2380  l_int32 ny,
2381  l_int32 tw,
2382  l_int32 spacing,
2383  l_int32 border,
2384  l_int32 fontsize)
2385 {
2386 l_int32 i, j, k, nt, n2, nout, d;
2387 char *str;
2388 L_BMF *bmf;
2389 PIX *pix1, *pix2, *pix3, *pix4;
2390 PIXA *pixa1, *pixad;
2391 
2392  PROCNAME("pixaConvertToNUpPixa");
2393 
2394  if (!pixas)
2395  return (PIXA *)ERROR_PTR("pixas not defined", procName, NULL);
2396  if (nx < 1 || ny < 1 || nx > 50 || ny > 50)
2397  return (PIXA *)ERROR_PTR("invalid tiling N-factor", procName, NULL);
2398  if (tw < 20)
2399  return (PIXA *)ERROR_PTR("tw must be >= 20", procName, NULL);
2400  if (fontsize < 0 || fontsize > 20 || fontsize & 1 || fontsize == 2)
2401  return (PIXA *)ERROR_PTR("invalid fontsize", procName, NULL);
2402 
2403  nt = pixaGetCount(pixas);
2404  if (sa && (sarrayGetCount(sa) != nt)) {
2405  L_WARNING("pixa size %d not equal to sarray size %d\n", procName,
2406  nt, sarrayGetCount(sa));
2407  }
2408 
2409  n2 = nx * ny;
2410  nout = (nt + n2 - 1) / n2;
2411  pixad = pixaCreate(nout);
2412  bmf = (fontsize == 0) ? NULL : bmfCreate(NULL, fontsize);
2413  for (i = 0, j = 0; i < nout; i++) {
2414  pixa1 = pixaCreate(n2);
2415  for (k = 0; k < n2 && j < nt; j++, k++) {
2416  pix1 = pixaGetPix(pixas, j, L_CLONE);
2417  pix2 = pixScaleToSize(pix1, tw, 0); /* all images have width tw */
2418  if (bmf && sa) {
2419  str = sarrayGetString(sa, j, L_NOCOPY);
2420  pix3 = pixAddTextlines(pix2, bmf, str, 0xff000000,
2421  L_ADD_BELOW);
2422  } else {
2423  pix3 = pixClone(pix2);
2424  }
2425  pixaAddPix(pixa1, pix3, L_INSERT);
2426  pixDestroy(&pix1);
2427  pixDestroy(&pix2);
2428  }
2429  if (pixaGetCount(pixa1) == 0) { /* probably won't happen */
2430  pixaDestroy(&pixa1);
2431  continue;
2432  }
2433 
2434  /* Add 2 * border to image width to prevent scaling */
2435  pixaGetRenderingDepth(pixa1, &d);
2436  pix4 = pixaDisplayTiledAndScaled(pixa1, d, tw + 2 * border, nx, 0,
2437  spacing, border);
2438  pixaAddPix(pixad, pix4, L_INSERT);
2439  pixaDestroy(&pixa1);
2440  }
2441 
2442  bmfDestroy(&bmf);
2443  return pixad;
2444 }
2445 
2446 
2447 /*---------------------------------------------------------------------*
2448  * Render two pixa side-by-side for comparison *
2449  *---------------------------------------------------------------------*/
2489 l_int32
2491  PIXA *pixa2,
2492  l_int32 nx,
2493  l_int32 ny,
2494  l_int32 tw,
2495  l_int32 spacing,
2496  l_int32 border,
2497  l_int32 fontsize,
2498  const char *fileout)
2499 {
2500 l_int32 n1, n2, npairs;
2501 PIXA *pixa3, *pixa4, *pixa5;
2502 SARRAY *sa;
2503 
2504  PROCNAME("pixaCompareInPdf");
2505 
2506  if (!pixa1 || !pixa2)
2507  return ERROR_INT("pixa1 and pixa2 not both defined", procName, 1);
2508  if (nx < 1 || ny < 1 || nx > 20 || ny > 20)
2509  return ERROR_INT("invalid tiling factors", procName, 1);
2510  if (tw < 20)
2511  return ERROR_INT("invalid tw; tw must be >= 20", procName, 1);
2512  if (fontsize < 0 || fontsize > 20 || fontsize & 1 || fontsize == 2)
2513  return ERROR_INT("invalid fontsize", procName, 1);
2514  if (!fileout)
2515  return ERROR_INT("fileout not defined", procName, 1);
2516  n1 = pixaGetCount(pixa1);
2517  n2 = pixaGetCount(pixa2);
2518  if (n1 == 0 || n2 == 0)
2519  return ERROR_INT("at least one pixa is empty", procName, 1);
2520  if (n1 != n2)
2521  L_WARNING("sizes (%d, %d) differ; using the minimum in interleave\n",
2522  procName, n1, n2);
2523 
2524  /* Interleave the input pixa */
2525  if ((pixa3 = pixaInterleave(pixa1, pixa2, L_CLONE)) == NULL)
2526  return ERROR_INT("pixa3 not made", procName, 1);
2527 
2528  /* Scale the images if necessary and pair them up side/by/side */
2529  pixa4 = pixaConvertToNUpPixa(pixa3, NULL, 2, 1, tw, spacing, border, 0);
2530  pixaDestroy(&pixa3);
2531 
2532  /* Label the pairs and mosaic into pages without further scaling */
2533  npairs = pixaGetCount(pixa4);
2534  sa = (fontsize > 0) ? sarrayGenerateIntegers(npairs) : NULL;
2535  pixa5 = pixaConvertToNUpPixa(pixa4, sa, nx, ny,
2536  2 * tw + 4 * border + spacing,
2537  spacing, border, fontsize);
2538  pixaDestroy(&pixa4);
2539  sarrayDestroy(&sa);
2540 
2541  /* Output as pdf without scaling */
2542  pixaConvertToPdf(pixa5, 0, 1.0, 0, 0, NULL, fileout);
2543  pixaDestroy(&pixa5);
2544  return 0;
2545 }
2546 
2547 
PIX * pixaaDisplay(PIXAA *paa, l_int32 w, l_int32 h)
pixaaDisplay()
Definition: pixafunc2.c:1477
l_int32 pixCopyColormap(PIX *pixd, PIX *pixs)
pixCopyColormap()
Definition: pix1.c:735
PIXA * pixaInterleave(PIXA *pixa1, PIXA *pixa2, l_int32 copyflag)
pixaInterleave()
Definition: pixabasic.c:1646
void bmfDestroy(L_BMF **pbmf)
bmfDestroy()
Definition: bmf.c:166
PIX * pixConvertTo1(PIX *pixs, l_int32 threshold)
pixConvertTo1()
Definition: pixconv.c:2933
l_int32 lept_mkdir(const char *subdir)
lept_mkdir()
Definition: utils2.c:1880
PIX * pixScaleToGray(PIX *pixs, l_float32 scalefactor)
pixScaleToGray()
Definition: scale2.c:204
l_int32 numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:472
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3233
l_int32 lept_roundftoi(l_float32 fval)
lept_roundftoi()
Definition: utils1.c:537
SARRAY * sarrayGenerateIntegers(l_int32 n)
sarrayGenerateIntegers()
Definition: sarray2.c:648
l_int32 pixaGetDepthInfo(PIXA *pixa, l_int32 *pmaxdepth, l_int32 *psame)
pixaGetDepthInfo()
Definition: pixafunc1.c:2484
PIXA * pixaCreate(l_int32 n)
pixaCreate()
Definition: pixabasic.c:161
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:1708
Definition: pix.h:704
l_int32 numaGetMax(NUMA *na, l_float32 *pmaxval, l_int32 *pimaxloc)
numaGetMax()
Definition: numafunc1.c:473
l_int32 pixSetAllArbitrary(PIX *pix, l_uint32 val)
pixSetAllArbitrary()
Definition: pix2.c:864
l_int32 modifyTrailingSlash(char *path, size_t nbytes, l_int32 flag)
modifyTrailingSlash()
Definition: utils2.c:2915
PIXA * pixaaGetPixa(PIXAA *paa, l_int32 index, l_int32 accesstype)
pixaaGetPixa()
Definition: pixabasic.c:2112
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:428
PIX * pixaDisplayUnsplit(PIXA *pixa, l_int32 nx, l_int32 ny, l_int32 borderwidth, l_uint32 bordercolor)
pixaDisplayUnsplit()
Definition: pixafunc2.c:633
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:2081
PIX * pixConvertTo8(PIX *pixs, l_int32 cmapflag)
pixConvertTo8()
Definition: pixconv.c:3041
l_int32 pixaaGetCount(PIXAA *paa, NUMA **pna)
pixaaGetCount()
Definition: pixabasic.c:2063
l_int32 splitPathAtDirectory(const char *pathname, char **pdir, char **ptail)
splitPathAtDirectory()
Definition: utils2.c:2419
NUMA * numaMakeConstant(l_float32 val, l_int32 size)
numaMakeConstant()
Definition: numafunc1.c:768
l_int32 boxaAddBox(BOXA *boxa, BOX *box, l_int32 copyflag)
boxaAddBox()
Definition: boxbasic.c:615
PIX * pixaDisplayOnLattice(PIXA *pixa, l_int32 cellw, l_int32 cellh, l_int32 *pncols, BOXA **pboxa)
pixaDisplayOnLattice()
Definition: pixafunc2.c:522
l_int32 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:2160
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:302
SARRAY * sarrayCreate(l_int32 n)
sarrayCreate()
Definition: sarray1.c:157
PIXA * pixaConvertToSameDepth(PIXA *pixas)
pixaConvertToSameDepth()
Definition: pixafunc1.c:2533
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:186
void boxaDestroy(BOXA **pboxa)
boxaDestroy()
Definition: boxbasic.c:577
l_int32 pixaAnyColormaps(PIXA *pixa, l_int32 *phascmap)
pixaAnyColormaps()
Definition: pixafunc1.c:2445
l_int32 boxaGetBoxGeometry(BOXA *boxa, l_int32 index, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxaGetBoxGeometry()
Definition: boxbasic.c:860
PIX * pixaDisplay(PIXA *pixa, l_int32 w, l_int32 h)
pixaDisplay()
Definition: pixafunc2.c:179
Definition: pix.h:492
PIX * pixaDisplayTiledInColumns(PIXA *pixas, l_int32 nx, l_float32 scalefactor, l_int32 spacing, l_int32 border)
pixaDisplayTiledInColumns()
Definition: pixafunc2.c:1005
l_int32 pixaaVerifyDepth(PIXAA *paa, l_int32 *psame, l_int32 *pmaxd)
pixaaVerifyDepth()
Definition: pixabasic.c:2207
l_int32 pixaVerifyDepth(PIXA *pixa, l_int32 *psame, l_int32 *pmaxd)
pixaVerifyDepth()
Definition: pixabasic.c:929
l_int32 pixaSizeRange(PIXA *pixa, l_int32 *pminw, l_int32 *pminh, l_int32 *pmaxw, l_int32 *pmaxh)
pixaSizeRange()
Definition: pixafunc1.c:2202
Definition: bmf.h:45
Definition: array.h:116
PIX * pixAddBorder(PIX *pixs, l_int32 npix, l_uint32 val)
pixAddBorder()
Definition: pix2.c:1736
PIXA * pixaConvertTo8(PIXA *pixas, l_int32 cmapflag)
pixaConvertTo8()
Definition: pixafunc2.c:1797
PIXA * pixaCopy(PIXA *pixa, l_int32 copyflag)
pixaCopy()
Definition: pixabasic.c:440
l_int32 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:2001
l_int32 * numaGetIArray(NUMA *na)
numaGetIArray()
Definition: numabasic.c:819
l_int32 pixRasterop(PIX *pixd, l_int32 dx, l_int32 dy, l_int32 dw, l_int32 dh, l_int32 op, PIX *pixs, l_int32 sx, l_int32 sy)
pixRasterop()
Definition: rop.c:193
PIXA * pixaConstrainedSelect(PIXA *pixas, l_int32 first, l_int32 last, l_int32 nmax, l_int32 use_pairs, l_int32 copyflag)
pixaConstrainedSelect()
Definition: pixafunc2.c:1933
NUMA * genConstrainedNumaInRange(l_int32 first, l_int32 last, l_int32 nmax, l_int32 use_pairs)
genConstrainedNumaInRange()
Definition: numafunc2.c:3032
PIX * pixaDisplayRandomCmap(PIXA *pixa, l_int32 w, l_int32 h)
pixaDisplayRandomCmap()
Definition: pixafunc2.c:354
Definition: array.h:59
static const l_int32 L_INSERT
Definition: pix.h:710
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:1374
l_int32 numaGetCount(NUMA *na)
numaGetCount()
Definition: numabasic.c:630
l_int32 pixaWrite(const char *filename, PIXA *pixa)
pixaWrite()
Definition: pixabasic.c:2646
l_int32 pixaGetPixDimensions(PIXA *pixa, l_int32 index, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixaGetPixDimensions()
Definition: pixabasic.c:695
l_int32 pixaAddPix(PIXA *pixa, PIX *pix, l_int32 copyflag)
pixaAddPix()
Definition: pixabasic.c:493
l_int32 pixaGetRenderingDepth(PIXA *pixa, l_int32 *pdepth)
pixaGetRenderingDepth()
Definition: pixafunc1.c:2367
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:821
PIXA * pixaSelectBySize(PIXA *pixas, l_int32 width, l_int32 height, l_int32 type, l_int32 relation, l_int32 *pchanged)
pixaSelectBySize()
Definition: pixafunc1.c:291
PIX * pixConvertTo8Colormap(PIX *pixs, l_int32 dither)
pixConvertTo8Colormap()
Definition: pixconv.c:3149
l_int32 pixSetColormap(PIX *pix, PIXCMAP *colormap)
pixSetColormap()
Definition: pix1.c:1556
char * sarrayGetString(SARRAY *sa, l_int32 index, l_int32 copyflag)
sarrayGetString()
Definition: sarray1.c:675
#define PIX_PAINT
Definition: pix.h:333
PIX * pixaDisplayOnColor(PIXA *pixa, l_int32 w, l_int32 h, l_uint32 bgcolor)
pixaDisplayOnColor()
Definition: pixafunc2.c:259
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:517
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:1122
l_int32 sarrayAddString(SARRAY *sa, char *string, l_int32 copyflag)
sarrayAddString()
Definition: sarray1.c:439
PIX * pixScaleToSize(PIX *pixs, l_int32 wd, l_int32 hd)
pixScaleToSize()
Definition: scale1.c:316
l_int32 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:749
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:545
NUMA * numaMakeSequence(l_float32 startval, l_float32 increment, l_int32 size)
numaMakeSequence()
Definition: numafunc1.c:737
SARRAY * getSortedPathnamesInDirectory(const char *dirname, const char *substr, l_int32 first, l_int32 nfiles)
getSortedPathnamesInDirectory()
Definition: sarray1.c:1710
Definition: pix.h:454
PIX * pixaaDisplayByPixa(PIXAA *paa, l_int32 xspace, l_int32 yspace, l_int32 maxw)
pixaaDisplayByPixa()
Definition: pixafunc2.c:1571
PIXA * pixaReadFilesSA(SARRAY *sa)
pixaReadFilesSA()
Definition: readfile.c:150
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:359
Definition: pix.h:465
l_int32 pixSetResolution(PIX *pix, l_int32 xres, l_int32 yres)
pixSetResolution()
Definition: pix1.c:1323
l_int32 pixSetBlackOrWhite(PIX *pixs, l_int32 op)
pixSetBlackOrWhite()
Definition: pix2.c:934
l_int32 makeTempDirname(char *result, size_t nbytes, const char *subdir)
makeTempDirname()
Definition: utils2.c:2865
l_int32 sarrayGetCount(SARRAY *sa)
sarrayGetCount()
Definition: sarray1.c:615
char * pixGetText(PIX *pix)
pixGetText()
Definition: pix1.c:1442
l_int32 boxaWriteMem(l_uint8 **pdata, size_t *psize, BOXA *boxa)
boxaWriteMem()
Definition: boxbasic.c:2266
PIX * pixaGetPix(PIXA *pixa, l_int32 index, l_int32 accesstype)
pixaGetPix()
Definition: pixabasic.c:660
Definition: pix.h:705
l_int32 pixaGetBoxGeometry(PIXA *pixa, l_int32 index, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
pixaGetBoxGeometry()
Definition: pixabasic.c:823
Definition: pix.h:134
l_int32 numaSetValue(NUMA *na, l_int32 index, l_float32 val)
numaSetValue()
Definition: numabasic.c:758
Definition: pix.h:706
l_int32 pixaAddBox(PIXA *pixa, BOX *box, l_int32 copyflag)
pixaAddBox()
Definition: pixabasic.c:537
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:2311
BOXA * boxaCreate(l_int32 n)
boxaCreate()
Definition: boxbasic.c:496
l_int32 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:2249
#define PIX_SRC
Definition: pix.h:327
PIXA * pixaConvertTo32(PIXA *pixas)
pixaConvertTo32()
Definition: pixafunc2.c:1880
l_int32 boxaGetExtent(BOXA *boxa, l_int32 *pw, l_int32 *ph, BOX **pbox)
boxaGetExtent()
Definition: boxfunc4.c:2321
PIX * pixConvert1To8(PIX *pixd, PIX *pixs, l_uint8 val0, l_uint8 val1)
pixConvert1To8()
Definition: pixconv.c:2366
PIXA * pixaConvertTo8Colormap(PIXA *pixas, l_int32 dither)
pixaConvertTo8Colormap()
Definition: pixafunc2.c:1838
PIX * pixAddTextlines(PIX *pixs, L_BMF *bmf, const char *textstr, l_uint32 val, l_int32 location)
pixAddTextlines()
Definition: textops.c:270
l_int32 boxaGetCount(BOXA *boxa)
boxaGetCount()
Definition: boxbasic.c:715
l_int32 numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition: numabasic.c:726
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:2377
BOXA * pixaaGetBoxa(PIXAA *paa, l_int32 accesstype)
pixaaGetBoxa()
Definition: pixabasic.c:2150
l_int32 pixSetAll(PIX *pix)
pixSetAll()
Definition: pix2.c:729
l_int32 pixGetDimensions(PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1052
PIXA * pixaConvertTo1(PIXA *pixas, l_int32 thresh)
pixaConvertTo1()
Definition: pixafunc2.c:1756
PIXA * pixaSelectRange(PIXA *pixas, l_int32 first, l_int32 last, l_int32 copyflag)
pixaSelectRange()
Definition: pixafunc1.c:1660
l_int32 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:2490
l_int32 lept_rmdir(const char *subdir)
lept_rmdir()
Definition: utils2.c:1951
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:1275
l_int32 pixaaSizeRange(PIXAA *paa, l_int32 *pminw, l_int32 *pminh, l_int32 *pmaxw, l_int32 *pmaxh)
pixaaSizeRange()
Definition: pixafunc1.c:2148
Definition: pix.h:480
PIX * pixScale(PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScale()
Definition: scale1.c:243
void pixaDestroy(PIXA **ppixa)
pixaDestroy()
Definition: pixabasic.c:398
PIX * pixAddSingleTextblock(PIX *pixs, L_BMF *bmf, const char *textstr, l_uint32 val, l_int32 location, l_int32 *poverflow)
pixAddSingleTextblock()
Definition: textops.c:115
l_int32 pixaSetBoxa(PIXA *pixa, BOXA *boxa, l_int32 accesstype)
pixaSetBoxa()
Definition: pixabasic.c:865
BOX * boxCreate(l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxCreate()
Definition: boxbasic.c:164
l_int32 pixaGetCount(PIXA *pixa)
pixaGetCount()
Definition: pixabasic.c:620
PIX * pixAddBorderGeneral(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_uint32 val)
pixAddBorderGeneral()
Definition: pix2.c:1830
l_int32 pixSetText(PIX *pix, const char *textstring)
pixSetText()
Definition: pix1.c:1466
PIXA * pixaAddTextNumber(PIXA *pixas, L_BMF *bmf, NUMA *na, l_uint32 val, l_int32 location)
pixaAddTextNumber()
Definition: textops.c:641
void sarrayDestroy(SARRAY **psa)
sarrayDestroy()
Definition: sarray1.c:349
PIX * pixaDisplayTiled(PIXA *pixa, l_int32 maxwidth, l_int32 background, l_int32 spacing)
pixaDisplayTiled()
Definition: pixafunc2.c:708
PIXCMAP * pixcmapCreateRandom(l_int32 depth, l_int32 hasblack, l_int32 haswhite)
pixcmapCreateRandom()
Definition: colormap.c:157
L_BMF * bmfCreate(const char *dir, l_int32 fontsize)
bmfCreate()
Definition: bmf.c:114
BOXA * pixaGetBoxa(PIXA *pixa, l_int32 accesstype)
pixaGetBoxa()
Definition: pixabasic.c:729