Leptonica  1.82.0
Image processing and image analysis suite
pixabasic.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 
135 #ifdef HAVE_CONFIG_H
136 #include <config_auto.h>
137 #endif /* HAVE_CONFIG_H */
138 
139 #include <string.h>
140 #include "allheaders.h"
141 
142  /* Bounds on array sizes */
143 static const size_t MaxInitPtrArraySize = 100000;
144 static const size_t MaxPixaPtrArraySize = 5000000;
145 static const size_t MaxPixaaPtrArraySize = 1000000;
146 static const size_t InitialPtrArraySize = 20;
148  /* Static functions */
149 static l_int32 pixaExtendArray(PIXA *pixa);
150 static l_int32 pixaaExtendArray(PIXAA *paa);
151 
152 /*---------------------------------------------------------------------*
153  * Pixa creation, destruction, copy *
154  *---------------------------------------------------------------------*/
166 PIXA *
167 pixaCreate(l_int32 n)
168 {
169 PIXA *pixa;
170 
171  PROCNAME("pixaCreate");
172 
173  if (n <= 0 || n > MaxInitPtrArraySize)
175 
176  pixa = (PIXA *)LEPT_CALLOC(1, sizeof(PIXA));
177  pixa->n = 0;
178  pixa->nalloc = n;
179  pixa->refcount = 1;
180  pixa->pix = (PIX **)LEPT_CALLOC(n, sizeof(PIX *));
181  pixa->boxa = boxaCreate(n);
182  if (!pixa->pix || !pixa->boxa) {
183  pixaDestroy(&pixa);
184  return (PIXA *)ERROR_PTR("pix or boxa not made", procName, NULL);
185  }
186  return pixa;
187 }
188 
189 
205 PIXA *
207  l_int32 n,
208  l_int32 cellw,
209  l_int32 cellh)
210 {
211 l_int32 w, h, d, nw, nh, i, j, index;
212 PIX *pix1, *pix2;
213 PIXA *pixa;
214 
215  PROCNAME("pixaCreateFromPix");
216 
217  if (!pixs)
218  return (PIXA *)ERROR_PTR("pixs not defined", procName, NULL);
219  if (n <= 0)
220  return (PIXA *)ERROR_PTR("n must be > 0", procName, NULL);
221 
222  if ((pixa = pixaCreate(n)) == NULL)
223  return (PIXA *)ERROR_PTR("pixa not made", procName, NULL);
224  pixGetDimensions(pixs, &w, &h, &d);
225  if ((pix1 = pixCreate(cellw, cellh, d)) == NULL) {
226  pixaDestroy(&pixa);
227  return (PIXA *)ERROR_PTR("pix1 not made", procName, NULL);
228  }
229 
230  nw = (w + cellw - 1) / cellw;
231  nh = (h + cellh - 1) / cellh;
232  for (i = 0, index = 0; i < nh; i++) {
233  for (j = 0; j < nw && index < n; j++, index++) {
234  pixRasterop(pix1, 0, 0, cellw, cellh, PIX_SRC, pixs,
235  j * cellw, i * cellh);
236  if (d == 1 && !pixClipToForeground(pix1, &pix2, NULL))
237  pixaAddPix(pixa, pix2, L_INSERT);
238  else
239  pixaAddPix(pixa, pix1, L_COPY);
240  }
241  }
242 
243  pixDestroy(&pix1);
244  return pixa;
245 }
246 
247 
271 PIXA *
273  BOXA *boxa,
274  l_int32 start,
275  l_int32 num,
276  l_int32 *pcropwarn)
277 {
278 l_int32 i, n, end, w, h, wbox, hbox, cropwarn;
279 BOX *box, *boxc;
280 PIX *pixd;
281 PIXA *pixad;
282 
283  PROCNAME("pixaCreateFromBoxa");
284 
285  if (!pixs)
286  return (PIXA *)ERROR_PTR("pixs not defined", procName, NULL);
287  if (!boxa)
288  return (PIXA *)ERROR_PTR("boxa not defined", procName, NULL);
289  if (num < 0)
290  return (PIXA *)ERROR_PTR("num must be >= 0", procName, NULL);
291 
292  n = boxaGetCount(boxa);
293  end = (num == 0) ? n - 1 : L_MIN(start + num - 1, n - 1);
294  if ((pixad = pixaCreate(end - start + 1)) == NULL)
295  return (PIXA *)ERROR_PTR("pixad not made", procName, NULL);
296 
297  boxaGetExtent(boxa, &wbox, &hbox, NULL);
298  pixGetDimensions(pixs, &w, &h, NULL);
299  cropwarn = FALSE;
300  if (wbox > w || hbox > h)
301  cropwarn = TRUE;
302  if (pcropwarn)
303  *pcropwarn = cropwarn;
304 
305  for (i = start; i <= end; i++) {
306  box = boxaGetBox(boxa, i, L_COPY);
307  if (cropwarn) { /* if box is outside pixs, pixd is NULL */
308  pixd = pixClipRectangle(pixs, box, &boxc); /* may be NULL */
309  if (pixd) {
310  pixaAddPix(pixad, pixd, L_INSERT);
311  pixaAddBox(pixad, boxc, L_INSERT);
312  }
313  boxDestroy(&box);
314  } else {
315  pixd = pixClipRectangle(pixs, box, NULL);
316  pixaAddPix(pixad, pixd, L_INSERT);
317  pixaAddBox(pixad, box, L_INSERT);
318  }
319  }
320 
321  return pixad;
322 }
323 
324 
349 PIXA *
351  l_int32 nx,
352  l_int32 ny,
353  l_int32 borderwidth,
354  l_uint32 bordercolor)
355 {
356 l_int32 w, h, d, cellw, cellh, i, j;
357 PIX *pix1;
358 PIXA *pixa;
359 
360  PROCNAME("pixaSplitPix");
361 
362  if (!pixs)
363  return (PIXA *)ERROR_PTR("pixs not defined", procName, NULL);
364  if (nx <= 0 || ny <= 0)
365  return (PIXA *)ERROR_PTR("nx and ny must be > 0", procName, NULL);
366  borderwidth = L_MAX(0, borderwidth);
367 
368  if ((pixa = pixaCreate(nx * ny)) == NULL)
369  return (PIXA *)ERROR_PTR("pixa not made", procName, NULL);
370  pixGetDimensions(pixs, &w, &h, &d);
371  cellw = (w + nx - 1) / nx; /* round up */
372  cellh = (h + ny - 1) / ny;
373 
374  for (i = 0; i < ny; i++) {
375  for (j = 0; j < nx; j++) {
376  if ((pix1 = pixCreate(cellw + 2 * borderwidth,
377  cellh + 2 * borderwidth, d)) == NULL) {
378  pixaDestroy(&pixa);
379  return (PIXA *)ERROR_PTR("pix1 not made", procName, NULL);
380  }
381  pixCopyColormap(pix1, pixs);
382  if (borderwidth == 0) { /* initialize full image to white */
383  if (d == 1)
384  pixClearAll(pix1);
385  else
386  pixSetAll(pix1);
387  } else {
388  pixSetAllArbitrary(pix1, bordercolor);
389  }
390  pixRasterop(pix1, borderwidth, borderwidth, cellw, cellh,
391  PIX_SRC, pixs, j * cellw, i * cellh);
392  pixaAddPix(pixa, pix1, L_INSERT);
393  }
394  }
395 
396  return pixa;
397 }
398 
399 
411 void
413 {
414 l_int32 i;
415 PIXA *pixa;
416 
417  PROCNAME("pixaDestroy");
418 
419  if (ppixa == NULL) {
420  L_WARNING("ptr address is NULL!\n", procName);
421  return;
422  }
423 
424  if ((pixa = *ppixa) == NULL)
425  return;
426 
427  /* Decrement the refcount. If it is 0, destroy the pixa. */
428  pixaChangeRefcount(pixa, -1);
429  if (pixa->refcount <= 0) {
430  for (i = 0; i < pixa->n; i++)
431  pixDestroy(&pixa->pix[i]);
432  LEPT_FREE(pixa->pix);
433  boxaDestroy(&pixa->boxa);
434  LEPT_FREE(pixa);
435  }
436 
437  *ppixa = NULL;
438 }
439 
440 
452 PIXA *
454  l_int32 copyflag)
455 {
456 l_int32 i, nb;
457 BOX *boxc;
458 PIX *pixc;
459 PIXA *pixac;
460 
461  PROCNAME("pixaCopy");
462 
463  if (!pixa)
464  return (PIXA *)ERROR_PTR("pixa not defined", procName, NULL);
465 
466  if (copyflag == L_CLONE) {
467  pixaChangeRefcount(pixa, 1);
468  return pixa;
469  }
470 
471  if (copyflag != L_COPY && copyflag != L_COPY_CLONE)
472  return (PIXA *)ERROR_PTR("invalid copyflag", procName, NULL);
473 
474  if ((pixac = pixaCreate(pixa->n)) == NULL)
475  return (PIXA *)ERROR_PTR("pixac not made", procName, NULL);
476  nb = pixaGetBoxaCount(pixa);
477  for (i = 0; i < pixa->n; i++) {
478  if (copyflag == L_COPY) {
479  pixc = pixaGetPix(pixa, i, L_COPY);
480  if (i < nb) boxc = pixaGetBox(pixa, i, L_COPY);
481  } else { /* copy-clone */
482  pixc = pixaGetPix(pixa, i, L_CLONE);
483  if (i < nb) boxc = pixaGetBox(pixa, i, L_CLONE);
484  }
485  pixaAddPix(pixac, pixc, L_INSERT);
486  if (i < nb) pixaAddBox(pixac, boxc, L_INSERT);
487  }
488 
489  return pixac;
490 }
491 
492 
493 
494 /*---------------------------------------------------------------------*
495  * Pixa addition *
496  *---------------------------------------------------------------------*/
505 l_ok
507  PIX *pix,
508  l_int32 copyflag)
509 {
510 l_int32 n;
511 PIX *pixc;
512 
513  PROCNAME("pixaAddPix");
514 
515  if (!pixa)
516  return ERROR_INT("pixa not defined", procName, 1);
517  if (!pix)
518  return ERROR_INT("pix not defined", procName, 1);
519 
520  if (copyflag == L_INSERT)
521  pixc = pix;
522  else if (copyflag == L_COPY)
523  pixc = pixCopy(NULL, pix);
524  else if (copyflag == L_CLONE)
525  pixc = pixClone(pix);
526  else
527  return ERROR_INT("invalid copyflag", procName, 1);
528  if (!pixc)
529  return ERROR_INT("pixc not made", procName, 1);
530 
531  n = pixaGetCount(pixa);
532  if (n >= pixa->nalloc) {
533  if (pixaExtendArray(pixa)) {
534  if (copyflag != L_INSERT)
535  pixDestroy(&pixc);
536  return ERROR_INT("extension failed", procName, 1);
537  }
538  }
539 
540  pixa->pix[n] = pixc;
541  pixa->n++;
542  return 0;
543 }
544 
545 
554 l_ok
556  BOX *box,
557  l_int32 copyflag)
558 {
559  PROCNAME("pixaAddBox");
560 
561  if (!pixa)
562  return ERROR_INT("pixa not defined", procName, 1);
563  if (!box)
564  return ERROR_INT("box not defined", procName, 1);
565  if (copyflag != L_INSERT && copyflag != L_COPY && copyflag != L_CLONE)
566  return ERROR_INT("invalid copyflag", procName, 1);
567 
568  boxaAddBox(pixa->boxa, box, copyflag);
569  return 0;
570 }
571 
572 
585 static l_int32
587 {
588  PROCNAME("pixaExtendArray");
589 
590  if (!pixa)
591  return ERROR_INT("pixa not defined", procName, 1);
592 
593  return pixaExtendArrayToSize(pixa, 2 * pixa->nalloc);
594 }
595 
596 
611 l_ok
613  size_t size)
614 {
615 size_t oldsize, newsize;
616 
617  PROCNAME("pixaExtendArrayToSize");
618 
619  if (!pixa)
620  return ERROR_INT("pixa not defined", procName, 1);
621  if (pixa->nalloc > MaxPixaPtrArraySize) /* belt & suspenders */
622  return ERROR_INT("pixa has too many ptrs", procName, 1);
623  if (size > MaxPixaPtrArraySize)
624  return ERROR_INT("size > 5M ptrs; too large", procName, 1);
625  if (size <= pixa->nalloc) {
626  L_INFO("size too small; no extension\n", procName);
627  return 0;
628  }
629 
630  oldsize = pixa->nalloc * sizeof(PIX *);
631  newsize = size * sizeof(PIX *);
632  if ((pixa->pix = (PIX **)reallocNew((void **)&pixa->pix,
633  oldsize, newsize)) == NULL)
634  return ERROR_INT("new ptr array not returned", procName, 1);
635  pixa->nalloc = size;
636  return boxaExtendArrayToSize(pixa->boxa, size);
637 }
638 
639 
640 /*---------------------------------------------------------------------*
641  * Pixa accessors *
642  *---------------------------------------------------------------------*/
649 l_int32
651 {
652  PROCNAME("pixaGetCount");
653 
654  if (!pixa)
655  return ERROR_INT("pixa not defined", procName, 0);
656 
657  return pixa->n;
658 }
659 
660 
668 l_ok
670  l_int32 delta)
671 {
672  PROCNAME("pixaChangeRefcount");
673 
674  if (!pixa)
675  return ERROR_INT("pixa not defined", procName, 1);
676 
677  pixa->refcount += delta;
678  return 0;
679 }
680 
681 
690 PIX *
692  l_int32 index,
693  l_int32 accesstype)
694 {
695 PIX *pix;
696 
697  PROCNAME("pixaGetPix");
698 
699  if (!pixa)
700  return (PIX *)ERROR_PTR("pixa not defined", procName, NULL);
701  if (index < 0 || index >= pixa->n)
702  return (PIX *)ERROR_PTR("index not valid", procName, NULL);
703  if ((pix = pixa->pix[index]) == NULL) {
704  L_ERROR("no pix at pixa[%d]\n", procName, index);
705  return (PIX *)ERROR_PTR("pix not found!", procName, NULL);
706  }
707 
708  if (accesstype == L_COPY)
709  return pixCopy(NULL, pix);
710  else if (accesstype == L_CLONE)
711  return pixClone(pix);
712  else
713  return (PIX *)ERROR_PTR("invalid accesstype", procName, NULL);
714 }
715 
716 
725 l_ok
727  l_int32 index,
728  l_int32 *pw,
729  l_int32 *ph,
730  l_int32 *pd)
731 {
732 PIX *pix;
733 
734  PROCNAME("pixaGetPixDimensions");
735 
736  if (pw) *pw = 0;
737  if (ph) *ph = 0;
738  if (pd) *pd = 0;
739  if (!pixa)
740  return ERROR_INT("pixa not defined", procName, 1);
741  if (index < 0 || index >= pixa->n)
742  return ERROR_INT("index not valid", procName, 1);
743 
744  if ((pix = pixaGetPix(pixa, index, L_CLONE)) == NULL)
745  return ERROR_INT("pix not found!", procName, 1);
746  pixGetDimensions(pix, pw, ph, pd);
747  pixDestroy(&pix);
748  return 0;
749 }
750 
751 
759 BOXA *
761  l_int32 accesstype)
762 {
763  PROCNAME("pixaGetBoxa");
764 
765  if (!pixa)
766  return (BOXA *)ERROR_PTR("pixa not defined", procName, NULL);
767  if (!pixa->boxa)
768  return (BOXA *)ERROR_PTR("boxa not defined", procName, NULL);
769  if (accesstype != L_COPY && accesstype != L_CLONE &&
770  accesstype != L_COPY_CLONE)
771  return (BOXA *)ERROR_PTR("invalid accesstype", procName, NULL);
772 
773  return boxaCopy(pixa->boxa, accesstype);
774 }
775 
776 
783 l_int32
785 {
786  PROCNAME("pixaGetBoxaCount");
787 
788  if (!pixa)
789  return ERROR_INT("pixa not defined", procName, 0);
790 
791  return boxaGetCount(pixa->boxa);
792 }
793 
794 
815 BOX *
817  l_int32 index,
818  l_int32 accesstype)
819 {
820 BOX *box;
821 
822  PROCNAME("pixaGetBox");
823 
824  if (!pixa)
825  return (BOX *)ERROR_PTR("pixa not defined", procName, NULL);
826  if (!pixa->boxa)
827  return (BOX *)ERROR_PTR("boxa not defined", procName, NULL);
828  if (index < 0 || index >= pixa->boxa->n)
829  return (BOX *)ERROR_PTR("index not valid", procName, NULL);
830  if (accesstype != L_COPY && accesstype != L_CLONE)
831  return (BOX *)ERROR_PTR("invalid accesstype", procName, NULL);
832 
833  box = pixa->boxa->box[index];
834  if (box) {
835  if (accesstype == L_COPY)
836  return boxCopy(box);
837  else /* accesstype == L_CLONE */
838  return boxClone(box);
839  } else {
840  return NULL;
841  }
842 }
843 
844 
853 l_ok
855  l_int32 index,
856  l_int32 *px,
857  l_int32 *py,
858  l_int32 *pw,
859  l_int32 *ph)
860 {
861 BOX *box;
862 
863  PROCNAME("pixaGetBoxGeometry");
864 
865  if (px) *px = 0;
866  if (py) *py = 0;
867  if (pw) *pw = 0;
868  if (ph) *ph = 0;
869  if (!pixa)
870  return ERROR_INT("pixa not defined", procName, 1);
871  if (index < 0 || index >= pixa->n)
872  return ERROR_INT("index not valid", procName, 1);
873 
874  if ((box = pixaGetBox(pixa, index, L_CLONE)) == NULL)
875  return ERROR_INT("box not found!", procName, 1);
876  boxGetGeometry(box, px, py, pw, ph);
877  boxDestroy(&box);
878  return 0;
879 }
880 
881 
895 l_ok
897  BOXA *boxa,
898  l_int32 accesstype)
899 {
900  PROCNAME("pixaSetBoxa");
901 
902  if (!pixa)
903  return ERROR_INT("pixa not defined", procName, 1);
904  if (!boxa)
905  return ERROR_INT("boxa not defined", procName, 1);
906  if (accesstype != L_INSERT && accesstype != L_COPY &&
907  accesstype != L_CLONE)
908  return ERROR_INT("invalid access type", procName, 1);
909 
910  boxaDestroy(&pixa->boxa);
911  if (accesstype == L_INSERT)
912  pixa->boxa = boxa;
913  else
914  pixa->boxa = boxaCopy(boxa, accesstype);
915 
916  return 0;
917 }
918 
919 
934 PIX **
936 {
937  PROCNAME("pixaGetPixArray");
938 
939  if (!pixa)
940  return (PIX **)ERROR_PTR("pixa not defined", procName, NULL);
941 
942  return pixa->pix;
943 }
944 
945 
959 l_ok
961  l_int32 *psame,
962  l_int32 *pmaxd)
963 {
964 l_int32 i, n, d, maxd, same;
965 
966  PROCNAME("pixaVerifyDepth");
967 
968  if (pmaxd) *pmaxd = 0;
969  if (!psame)
970  return ERROR_INT("psame not defined", procName, 1);
971  if (!pixa)
972  return ERROR_INT("pixa not defined", procName, 1);
973  if ((n = pixaGetCount(pixa)) == 0)
974  return ERROR_INT("no pix in pixa", procName, 1);
975 
976  same = 1;
977  pixaGetPixDimensions(pixa, 0, NULL, NULL, &maxd);
978  for (i = 1; i < n; i++) {
979  if (pixaGetPixDimensions(pixa, i, NULL, NULL, &d))
980  return ERROR_INT("pix depth not found", procName, 1);
981  maxd = L_MAX(maxd, d);
982  if (d != maxd)
983  same = 0;
984  }
985  *psame = same;
986  if (pmaxd) *pmaxd = maxd;
987  return 0;
988 }
989 
990 
1005 l_ok
1007  l_int32 *psame,
1008  l_int32 *pmaxw,
1009  l_int32 *pmaxh)
1010 {
1011 l_int32 i, n, w, h, maxw, maxh, same;
1012 
1013  PROCNAME("pixaVerifyDimensions");
1014 
1015  if (pmaxw) *pmaxw = 0;
1016  if (pmaxh) *pmaxh = 0;
1017  if (!psame)
1018  return ERROR_INT("psame not defined", procName, 1);
1019  *psame = 0;
1020  if (!pixa)
1021  return ERROR_INT("pixa not defined", procName, 1);
1022  if ((n = pixaGetCount(pixa)) == 0)
1023  return ERROR_INT("no pix in pixa", procName, 1);
1024 
1025  same = 1;
1026  pixaGetPixDimensions(pixa, 0, &maxw, &maxh, NULL);
1027  for (i = 1; i < n; i++) {
1028  if (pixaGetPixDimensions(pixa, i, &w, &h, NULL))
1029  return ERROR_INT("pix dimensions not found", procName, 1);
1030  maxw = L_MAX(maxw, w);
1031  maxh = L_MAX(maxh, h);
1032  if (w != maxw || h != maxh)
1033  same = 0;
1034  }
1035  *psame = same;
1036  if (pmaxw) *pmaxw = maxw;
1037  if (pmaxh) *pmaxh = maxh;
1038  return 0;
1039 }
1040 
1041 
1056 l_ok
1058  l_int32 *pfullpa,
1059  l_int32 *pfullba)
1060 {
1061 l_int32 i, n, full;
1062 BOXA *boxa;
1063 PIX *pix;
1064 
1065  PROCNAME("pixaIsFull");
1066 
1067  if (pfullpa) *pfullpa = 0;
1068  if (pfullba) *pfullba = 0;
1069  if (!pixa)
1070  return ERROR_INT("pixa not defined", procName, 1);
1071 
1072  n = pixaGetCount(pixa);
1073  if (pfullpa) {
1074  full = 1;
1075  for (i = 0; i < n; i++) {
1076  if ((pix = pixaGetPix(pixa, i, L_CLONE)) == NULL) {
1077  full = 0;
1078  break;
1079  }
1080  pixDestroy(&pix);
1081  }
1082  *pfullpa = full;
1083  }
1084  if (pfullba) {
1085  boxa = pixaGetBoxa(pixa, L_CLONE);
1086  boxaIsFull(boxa, pfullba);
1087  boxaDestroy(&boxa);
1088  }
1089  return 0;
1090 }
1091 
1092 
1106 l_ok
1108  l_int32 *pntext)
1109 {
1110 char *text;
1111 l_int32 i, n;
1112 PIX *pix;
1113 
1114  PROCNAME("pixaCountText");
1115 
1116  if (!pntext)
1117  return ERROR_INT("&ntext not defined", procName, 1);
1118  *pntext = 0;
1119  if (!pixa)
1120  return ERROR_INT("pixa not defined", procName, 1);
1121 
1122  n = pixaGetCount(pixa);
1123  for (i = 0; i < n; i++) {
1124  if ((pix = pixaGetPix(pixa, i, L_CLONE)) == NULL)
1125  continue;
1126  text = pixGetText(pix);
1127  if (text && strlen(text) > 0)
1128  (*pntext)++;
1129  pixDestroy(&pix);
1130  }
1131 
1132  return 0;
1133 }
1134 
1135 
1154 l_ok
1156  const char *text,
1157  SARRAY *sa)
1158 {
1159 char *str;
1160 l_int32 i, n;
1161 PIX *pix;
1162 
1163  PROCNAME("pixaSetText");
1164 
1165  if (!pixa)
1166  return ERROR_INT("pixa not defined", procName, 1);
1167 
1168  n = pixaGetCount(pixa);
1169  if (sa && (sarrayGetCount(sa) != n))
1170  return ERROR_INT("pixa and sa sizes differ", procName, 1);
1171 
1172  if (!sa) {
1173  for (i = 0; i < n; i++) {
1174  if ((pix = pixaGetPix(pixa, i, L_CLONE)) == NULL)
1175  continue;
1176  pixSetText(pix, text);
1177  pixDestroy(&pix);
1178  }
1179  return 0;
1180  }
1181 
1182  for (i = 0; i < n; i++) {
1183  if ((pix = pixaGetPix(pixa, i, L_CLONE)) == NULL)
1184  continue;
1185  str = sarrayGetString(sa, i, L_NOCOPY);
1186  pixSetText(pix, str);
1187  pixDestroy(&pix);
1188  }
1189 
1190  return 0;
1191 }
1192 
1193 
1213 void ***
1215  l_int32 *psize)
1216 {
1217 l_int32 i, n, same;
1218 void **lineptrs;
1219 void ***lineset;
1220 PIX *pix;
1221 
1222  PROCNAME("pixaGetLinePtrs");
1223 
1224  if (psize) *psize = 0;
1225  if (!pixa)
1226  return (void ***)ERROR_PTR("pixa not defined", procName, NULL);
1227  pixaVerifyDepth(pixa, &same, NULL);
1228  if (!same)
1229  return (void ***)ERROR_PTR("pixa not all same depth", procName, NULL);
1230  n = pixaGetCount(pixa);
1231  if (psize) *psize = n;
1232  if ((lineset = (void ***)LEPT_CALLOC(n, sizeof(void **))) == NULL)
1233  return (void ***)ERROR_PTR("lineset not made", procName, NULL);
1234  for (i = 0; i < n; i++) {
1235  pix = pixaGetPix(pixa, i, L_CLONE);
1236  lineptrs = pixGetLinePtrs(pix, NULL);
1237  lineset[i] = lineptrs;
1238  pixDestroy(&pix);
1239  }
1240 
1241  return lineset;
1242 }
1243 
1244 
1245 /*---------------------------------------------------------------------*
1246  * Pixa output info *
1247  *---------------------------------------------------------------------*/
1261 l_ok
1263  PIXA *pixa)
1264 {
1265 char *text;
1266 l_int32 i, n, w, h, d, spp, count, hastext;
1267 PIX *pix;
1268 PIXCMAP *cmap;
1269 
1270  PROCNAME("pixaWriteStreamInfo");
1271 
1272  if (!fp)
1273  return ERROR_INT("stream not defined", procName, 1);
1274  if (!pixa)
1275  return ERROR_INT("pixa not defined", procName, 1);
1276 
1277  n = pixaGetCount(pixa);
1278  for (i = 0; i < n; i++) {
1279  if ((pix = pixaGetPix(pixa, i, L_CLONE)) == NULL) {
1280  fprintf(fp, "%d: no pix at this index\n", i);
1281  continue;
1282  }
1283  pixGetDimensions(pix, &w, &h, &d);
1284  spp = pixGetSpp(pix);
1285  text = pixGetText(pix);
1286  hastext = (text && strlen(text) > 0);
1287  if ((cmap = pixGetColormap(pix)) != NULL)
1288  count = pixcmapGetCount(cmap);
1289  fprintf(fp, "Pix %d: w = %d, h = %d, d = %d, spp = %d",
1290  i, w, h, d, spp);
1291  if (cmap) fprintf(fp, ", cmap(%d colors)", count);
1292  if (hastext) fprintf(fp, ", text = %s", text);
1293  fprintf(fp, "\n");
1294  pixDestroy(&pix);
1295  }
1296 
1297  return 0;
1298 }
1299 
1300 
1301 /*---------------------------------------------------------------------*
1302  * Pixa array modifiers *
1303  *---------------------------------------------------------------------*/
1319 l_ok
1321  l_int32 index,
1322  PIX *pix,
1323  BOX *box)
1324 {
1325 BOXA *boxa;
1326 
1327  PROCNAME("pixaReplacePix");
1328 
1329  if (!pixa)
1330  return ERROR_INT("pixa not defined", procName, 1);
1331  if (index < 0 || index >= pixa->n)
1332  return ERROR_INT("index not valid", procName, 1);
1333  if (!pix)
1334  return ERROR_INT("pix not defined", procName, 1);
1335 
1336  pixDestroy(&(pixa->pix[index]));
1337  pixa->pix[index] = pix;
1338 
1339  if (box) {
1340  boxa = pixa->boxa;
1341  if (index > boxa->n)
1342  return ERROR_INT("boxa index not valid", procName, 1);
1343  boxaReplaceBox(boxa, index, box);
1344  }
1345 
1346  return 0;
1347 }
1348 
1349 
1369 l_ok
1371  l_int32 index,
1372  PIX *pixs,
1373  BOX *box)
1374 {
1375 l_int32 i, n;
1376 
1377  PROCNAME("pixaInsertPix");
1378 
1379  if (!pixa)
1380  return ERROR_INT("pixa not defined", procName, 1);
1381  n = pixaGetCount(pixa);
1382  if (index < 0 || index > n) {
1383  L_ERROR("index %d not in [0,...,%d]\n", procName, index, n);
1384  return 1;
1385  }
1386  if (!pixs)
1387  return ERROR_INT("pixs not defined", procName, 1);
1388 
1389  if (n >= pixa->nalloc) { /* extend both ptr arrays */
1390  if (pixaExtendArray(pixa))
1391  return ERROR_INT("extension failed", procName, 1);
1392  if (boxaExtendArray(pixa->boxa))
1393  return ERROR_INT("extension failed", procName, 1);
1394  }
1395  pixa->n++;
1396  for (i = n; i > index; i--)
1397  pixa->pix[i] = pixa->pix[i - 1];
1398  pixa->pix[index] = pixs;
1399 
1400  /* Optionally, insert the box */
1401  if (box)
1402  boxaInsertBox(pixa->boxa, index, box);
1403  return 0;
1404 }
1405 
1406 
1422 l_ok
1424  l_int32 index)
1425 {
1426 l_int32 i, n, nbox;
1427 BOXA *boxa;
1428 PIX **array;
1429 
1430  PROCNAME("pixaRemovePix");
1431 
1432  if (!pixa)
1433  return ERROR_INT("pixa not defined", procName, 1);
1434  n = pixaGetCount(pixa);
1435  if (index < 0 || index >= n) {
1436  L_ERROR("index %d not in [0,...,%d]\n", procName, index, n - 1);
1437  return 1;
1438  }
1439 
1440  /* Remove the pix */
1441  array = pixa->pix;
1442  pixDestroy(&array[index]);
1443  for (i = index + 1; i < n; i++)
1444  array[i - 1] = array[i];
1445  array[n - 1] = NULL;
1446  pixa->n--;
1447 
1448  /* Remove the box if it exists */
1449  boxa = pixa->boxa;
1450  nbox = boxaGetCount(boxa);
1451  if (index < nbox)
1452  boxaRemoveBox(boxa, index);
1453 
1454  return 0;
1455 }
1456 
1457 
1476 l_ok
1478  l_int32 index,
1479  PIX **ppix,
1480  BOX **pbox)
1481 {
1482 l_int32 i, n, nbox;
1483 BOXA *boxa;
1484 PIX **array;
1485 
1486  PROCNAME("pixaRemovePixAndSave");
1487 
1488  if (ppix) *ppix = NULL;
1489  if (pbox) *pbox = NULL;
1490  if (!pixa)
1491  return ERROR_INT("pixa not defined", procName, 1);
1492  n = pixaGetCount(pixa);
1493  if (index < 0 || index >= n) {
1494  L_ERROR("index %d not in [0,...,%d]\n", procName, index, n - 1);
1495  return 1;
1496  }
1497 
1498  /* Remove the pix */
1499  array = pixa->pix;
1500  if (ppix)
1501  *ppix = pixaGetPix(pixa, index, L_CLONE);
1502  pixDestroy(&array[index]);
1503  for (i = index + 1; i < n; i++)
1504  array[i - 1] = array[i];
1505  array[n - 1] = NULL;
1506  pixa->n--;
1507 
1508  /* Remove the box if it exists */
1509  boxa = pixa->boxa;
1510  nbox = boxaGetCount(boxa);
1511  if (index < nbox)
1512  boxaRemoveBoxAndSave(boxa, index, pbox);
1513 
1514  return 0;
1515 }
1516 
1517 
1530 l_ok
1532  NUMA *naindex)
1533 {
1534 l_int32 i, n, index;
1535 NUMA *na1;
1536 
1537  PROCNAME("pixaRemoveSelected");
1538 
1539  if (!pixa)
1540  return ERROR_INT("pixa not defined", procName, 1);
1541  if (!naindex)
1542  return ERROR_INT("naindex not defined", procName, 1);
1543  if ((n = numaGetCount(naindex)) == 0)
1544  return ERROR_INT("naindex is empty", procName, 1);
1545 
1546  /* Remove from highest indices first */
1547  na1 = numaSort(NULL, naindex, L_SORT_DECREASING);
1548  for (i = 0; i < n; i++) {
1549  numaGetIValue(na1, i, &index);
1550  pixaRemovePix(pixa, index);
1551  }
1552  numaDestroy(&na1);
1553  return 0;
1554 }
1555 
1556 
1592 l_ok
1594  PIX *pix,
1595  BOX *box)
1596 {
1597 l_int32 i, n;
1598 PIX *pix1;
1599 
1600  PROCNAME("pixaInitFull");
1601 
1602  if (!pixa)
1603  return ERROR_INT("pixa not defined", procName, 1);
1604 
1605  n = pixa->nalloc;
1606  pixa->n = n;
1607  for (i = 0; i < n; i++) {
1608  if (pix)
1609  pix1 = pixCopy(NULL, pix);
1610  else
1611  pix1 = pixCreate(1, 1, 1);
1612  pixaReplacePix(pixa, i, pix1, NULL);
1613  }
1614  if (box)
1615  boxaInitFull(pixa->boxa, box);
1616 
1617  return 0;
1618 }
1619 
1620 
1634 l_ok
1636 {
1637 l_int32 i, n;
1638 
1639  PROCNAME("pixaClear");
1640 
1641  if (!pixa)
1642  return ERROR_INT("pixa not defined", procName, 1);
1643 
1644  n = pixaGetCount(pixa);
1645  for (i = 0; i < n; i++)
1646  pixDestroy(&pixa->pix[i]);
1647  pixa->n = 0;
1648  return boxaClear(pixa->boxa);
1649 }
1650 
1651 
1652 /*---------------------------------------------------------------------*
1653  * Pixa and Pixaa combination *
1654  *---------------------------------------------------------------------*/
1672 l_ok
1674  PIXA *pixas,
1675  l_int32 istart,
1676  l_int32 iend)
1677 {
1678 l_int32 i, n, nb;
1679 BOXA *boxas, *boxad;
1680 PIX *pix;
1681 
1682  PROCNAME("pixaJoin");
1683 
1684  if (!pixad)
1685  return ERROR_INT("pixad not defined", procName, 1);
1686  if (!pixas || ((n = pixaGetCount(pixas)) == 0))
1687  return 0;
1688 
1689  if (istart < 0)
1690  istart = 0;
1691  if (iend < 0 || iend >= n)
1692  iend = n - 1;
1693  if (istart > iend)
1694  return ERROR_INT("istart > iend; nothing to add", procName, 1);
1695 
1696  for (i = istart; i <= iend; i++) {
1697  pix = pixaGetPix(pixas, i, L_CLONE);
1698  pixaAddPix(pixad, pix, L_INSERT);
1699  }
1700 
1701  boxas = pixaGetBoxa(pixas, L_CLONE);
1702  boxad = pixaGetBoxa(pixad, L_CLONE);
1703  nb = pixaGetBoxaCount(pixas);
1704  iend = L_MIN(iend, nb - 1);
1705  boxaJoin(boxad, boxas, istart, iend);
1706  boxaDestroy(&boxas); /* just the clones */
1707  boxaDestroy(&boxad);
1708  return 0;
1709 }
1710 
1711 
1728 PIXA *
1730  PIXA *pixa2,
1731  l_int32 copyflag)
1732 {
1733 l_int32 i, n1, n2, n, nb1, nb2;
1734 BOX *box;
1735 PIX *pix;
1736 PIXA *pixad;
1737 
1738  PROCNAME("pixaInterleave");
1739 
1740  if (!pixa1)
1741  return (PIXA *)ERROR_PTR("pixa1 not defined", procName, NULL);
1742  if (!pixa2)
1743  return (PIXA *)ERROR_PTR("pixa2 not defined", procName, NULL);
1744  if (copyflag != L_COPY && copyflag != L_CLONE)
1745  return (PIXA *)ERROR_PTR("invalid copyflag", procName, NULL);
1746  n1 = pixaGetCount(pixa1);
1747  n2 = pixaGetCount(pixa2);
1748  n = L_MIN(n1, n2);
1749  if (n == 0)
1750  return (PIXA *)ERROR_PTR("at least one input pixa is empty",
1751  procName, NULL);
1752  if (n1 != n2)
1753  L_WARNING("counts differ: %d != %d\n", procName, n1, n2);
1754 
1755  pixad = pixaCreate(2 * n);
1756  nb1 = pixaGetBoxaCount(pixa1);
1757  nb2 = pixaGetBoxaCount(pixa2);
1758  for (i = 0; i < n; i++) {
1759  pix = pixaGetPix(pixa1, i, copyflag);
1760  pixaAddPix(pixad, pix, L_INSERT);
1761  if (i < nb1) {
1762  box = pixaGetBox(pixa1, i, L_COPY);
1763  pixaAddBox(pixad, box, L_INSERT);
1764  }
1765  pix = pixaGetPix(pixa2, i, copyflag);
1766  pixaAddPix(pixad, pix, L_INSERT);
1767  if (i < nb2) {
1768  box = pixaGetBox(pixa2, i, L_COPY);
1769  pixaAddBox(pixad, box, L_INSERT);
1770  }
1771  }
1772 
1773  return pixad;
1774 }
1775 
1776 
1793 l_ok
1795  PIXAA *paas,
1796  l_int32 istart,
1797  l_int32 iend)
1798 {
1799 l_int32 i, n;
1800 PIXA *pixa;
1801 
1802  PROCNAME("pixaaJoin");
1803 
1804  if (!paad)
1805  return ERROR_INT("pixaad not defined", procName, 1);
1806  if (!paas)
1807  return 0;
1808 
1809  if (istart < 0)
1810  istart = 0;
1811  n = pixaaGetCount(paas, NULL);
1812  if (iend < 0 || iend >= n)
1813  iend = n - 1;
1814  if (istart > iend)
1815  return ERROR_INT("istart > iend; nothing to add", procName, 1);
1816 
1817  for (i = istart; i <= iend; i++) {
1818  pixa = pixaaGetPixa(paas, i, L_CLONE);
1819  pixaaAddPixa(paad, pixa, L_INSERT);
1820  }
1821 
1822  return 0;
1823 }
1824 
1825 
1826 /*---------------------------------------------------------------------*
1827  * Pixaa creation and destruction *
1828  *---------------------------------------------------------------------*/
1851 PIXAA *
1852 pixaaCreate(l_int32 n)
1853 {
1854 PIXAA *paa;
1855 
1856  PROCNAME("pixaaCreate");
1857 
1858  if (n <= 0 || n > MaxInitPtrArraySize)
1859  n = InitialPtrArraySize;
1860 
1861  paa = (PIXAA *)LEPT_CALLOC(1, sizeof(PIXAA));
1862  paa->n = 0;
1863  paa->nalloc = n;
1864  if ((paa->pixa = (PIXA **)LEPT_CALLOC(n, sizeof(PIXA *))) == NULL) {
1865  pixaaDestroy(&paa);
1866  return (PIXAA *)ERROR_PTR("pixa ptrs not made", procName, NULL);
1867  }
1868  paa->boxa = boxaCreate(n);
1869 
1870  return paa;
1871 }
1872 
1873 
1894 PIXAA *
1896  l_int32 n,
1897  l_int32 type,
1898  l_int32 copyflag)
1899 {
1900 l_int32 count, i, j, npixa;
1901 PIX *pix;
1902 PIXA *pixat;
1903 PIXAA *paa;
1904 
1905  PROCNAME("pixaaCreateFromPixa");
1906 
1907  if (!pixa)
1908  return (PIXAA *)ERROR_PTR("pixa not defined", procName, NULL);
1909  count = pixaGetCount(pixa);
1910  if (count == 0)
1911  return (PIXAA *)ERROR_PTR("no pix in pixa", procName, NULL);
1912  if (n <= 0)
1913  return (PIXAA *)ERROR_PTR("n must be > 0", procName, NULL);
1914  if (type != L_CHOOSE_CONSECUTIVE && type != L_CHOOSE_SKIP_BY)
1915  return (PIXAA *)ERROR_PTR("invalid type", procName, NULL);
1916  if (copyflag != L_CLONE && copyflag != L_COPY)
1917  return (PIXAA *)ERROR_PTR("invalid copyflag", procName, NULL);
1918 
1919  if (type == L_CHOOSE_CONSECUTIVE)
1920  npixa = (count + n - 1) / n;
1921  else /* L_CHOOSE_SKIP_BY */
1922  npixa = L_MIN(n, count);
1923  paa = pixaaCreate(npixa);
1924  if (type == L_CHOOSE_CONSECUTIVE) {
1925  for (i = 0; i < count; i++) {
1926  if (i % n == 0)
1927  pixat = pixaCreate(n);
1928  pix = pixaGetPix(pixa, i, copyflag);
1929  pixaAddPix(pixat, pix, L_INSERT);
1930  if (i % n == n - 1)
1931  pixaaAddPixa(paa, pixat, L_INSERT);
1932  }
1933  if (i % n != 0)
1934  pixaaAddPixa(paa, pixat, L_INSERT);
1935  } else { /* L_CHOOSE_SKIP_BY */
1936  for (i = 0; i < npixa; i++) {
1937  pixat = pixaCreate(count / npixa + 1);
1938  for (j = i; j < count; j += n) {
1939  pix = pixaGetPix(pixa, j, copyflag);
1940  pixaAddPix(pixat, pix, L_INSERT);
1941  }
1942  pixaaAddPixa(paa, pixat, L_INSERT);
1943  }
1944  }
1945 
1946  return paa;
1947 }
1948 
1949 
1956 void
1958 {
1959 l_int32 i;
1960 PIXAA *paa;
1961 
1962  PROCNAME("pixaaDestroy");
1963 
1964  if (ppaa == NULL) {
1965  L_WARNING("ptr address is NULL!\n", procName);
1966  return;
1967  }
1968 
1969  if ((paa = *ppaa) == NULL)
1970  return;
1971 
1972  for (i = 0; i < paa->n; i++)
1973  pixaDestroy(&paa->pixa[i]);
1974  LEPT_FREE(paa->pixa);
1975  boxaDestroy(&paa->boxa);
1976  LEPT_FREE(paa);
1977  *ppaa = NULL;
1978 }
1979 
1980 
1981 /*---------------------------------------------------------------------*
1982  * Pixaa addition *
1983  *---------------------------------------------------------------------*/
1997 l_ok
1999  PIXA *pixa,
2000  l_int32 copyflag)
2001 {
2002 l_int32 n;
2003 PIXA *pixac;
2004 
2005  PROCNAME("pixaaAddPixa");
2006 
2007  if (!paa)
2008  return ERROR_INT("paa not defined", procName, 1);
2009  if (!pixa)
2010  return ERROR_INT("pixa not defined", procName, 1);
2011  if (copyflag != L_INSERT && copyflag != L_COPY &&
2012  copyflag != L_CLONE && copyflag != L_COPY_CLONE)
2013  return ERROR_INT("invalid copyflag", procName, 1);
2014 
2015  if (copyflag == L_INSERT) {
2016  pixac = pixa;
2017  } else {
2018  if ((pixac = pixaCopy(pixa, copyflag)) == NULL)
2019  return ERROR_INT("pixac not made", procName, 1);
2020  }
2021 
2022  n = pixaaGetCount(paa, NULL);
2023  if (n >= paa->nalloc) {
2024  if (pixaaExtendArray(paa)) {
2025  if (copyflag != L_INSERT)
2026  pixaDestroy(&pixac);
2027  return ERROR_INT("extension failed", procName, 1);
2028  }
2029  }
2030  paa->pixa[n] = pixac;
2031  paa->n++;
2032  return 0;
2033 }
2034 
2035 
2047 static l_int32
2049 {
2050 size_t oldsize, newsize;
2051 
2052  PROCNAME("pixaaExtendArray");
2053 
2054  if (!paa)
2055  return ERROR_INT("paa not defined", procName, 1);
2056  if (paa->nalloc > MaxPixaaPtrArraySize) /* belt & suspenders */
2057  return ERROR_INT("paa has too many ptrs", procName, 1);
2058  oldsize = paa->nalloc * sizeof(PIXA *);
2059  newsize = 2 * oldsize;
2060  if (newsize > 8 * MaxPixaaPtrArraySize)
2061  return ERROR_INT("newsize > 8 MB; too large", procName, 1);
2062 
2063  if ((paa->pixa = (PIXA **)reallocNew((void **)&paa->pixa,
2064  oldsize, newsize)) == NULL)
2065  return ERROR_INT("new ptr array not returned", procName, 1);
2066 
2067  paa->nalloc *= 2;
2068  return 0;
2069 }
2070 
2071 
2082 l_ok
2084  l_int32 index,
2085  PIX *pix,
2086  BOX *box,
2087  l_int32 copyflag)
2088 {
2089 PIXA *pixa;
2090 
2091  PROCNAME("pixaaAddPix");
2092 
2093  if (!paa)
2094  return ERROR_INT("paa not defined", procName, 1);
2095  if (!pix)
2096  return ERROR_INT("pix not defined", procName, 1);
2097 
2098  if ((pixa = pixaaGetPixa(paa, index, L_CLONE)) == NULL)
2099  return ERROR_INT("pixa not found", procName, 1);
2100  pixaAddPix(pixa, pix, copyflag);
2101  if (box) pixaAddBox(pixa, box, copyflag);
2102  pixaDestroy(&pixa);
2103  return 0;
2104 }
2105 
2106 
2121 l_ok
2123  BOX *box,
2124  l_int32 copyflag)
2125 {
2126  PROCNAME("pixaaAddBox");
2127 
2128  if (!paa)
2129  return ERROR_INT("paa not defined", procName, 1);
2130  if (!box)
2131  return ERROR_INT("box not defined", procName, 1);
2132  if (copyflag != L_INSERT && copyflag != L_COPY && copyflag != L_CLONE)
2133  return ERROR_INT("invalid copyflag", procName, 1);
2134 
2135  boxaAddBox(paa->boxa, box, copyflag);
2136  return 0;
2137 }
2138 
2139 
2140 
2141 /*---------------------------------------------------------------------*
2142  * Pixaa accessors *
2143  *---------------------------------------------------------------------*/
2156 l_int32
2158  NUMA **pna)
2159 {
2160 l_int32 i, n;
2161 NUMA *na;
2162 PIXA *pixa;
2163 
2164  PROCNAME("pixaaGetCount");
2165 
2166  if (pna) *pna = NULL;
2167  if (!paa)
2168  return ERROR_INT("paa not defined", procName, 0);
2169 
2170  n = paa->n;
2171  if (pna) {
2172  if ((na = numaCreate(n)) == NULL)
2173  return ERROR_INT("na not made", procName, 0);
2174  *pna = na;
2175  for (i = 0; i < n; i++) {
2176  pixa = pixaaGetPixa(paa, i, L_CLONE);
2177  numaAddNumber(na, pixaGetCount(pixa));
2178  pixaDestroy(&pixa);
2179  }
2180  }
2181  return n;
2182 }
2183 
2184 
2205 PIXA *
2207  l_int32 index,
2208  l_int32 accesstype)
2209 {
2210 PIXA *pixa;
2211 
2212  PROCNAME("pixaaGetPixa");
2213 
2214  if (!paa)
2215  return (PIXA *)ERROR_PTR("paa not defined", procName, NULL);
2216  if (index < 0 || index >= paa->n)
2217  return (PIXA *)ERROR_PTR("index not valid", procName, NULL);
2218  if (accesstype != L_COPY && accesstype != L_CLONE &&
2219  accesstype != L_COPY_CLONE)
2220  return (PIXA *)ERROR_PTR("invalid accesstype", procName, NULL);
2221 
2222  if ((pixa = paa->pixa[index]) == NULL) { /* shouldn't happen! */
2223  L_ERROR("missing pixa[%d]\n", procName, index);
2224  return (PIXA *)ERROR_PTR("pixa not found at index", procName, NULL);
2225  }
2226  return pixaCopy(pixa, accesstype);
2227 }
2228 
2229 
2243 BOXA *
2245  l_int32 accesstype)
2246 {
2247  PROCNAME("pixaaGetBoxa");
2248 
2249  if (!paa)
2250  return (BOXA *)ERROR_PTR("paa not defined", procName, NULL);
2251  if (accesstype != L_COPY && accesstype != L_CLONE)
2252  return (BOXA *)ERROR_PTR("invalid access type", procName, NULL);
2253 
2254  return boxaCopy(paa->boxa, accesstype);
2255 }
2256 
2257 
2267 PIX *
2269  l_int32 index,
2270  l_int32 ipix,
2271  l_int32 accessflag)
2272 {
2273 PIX *pix;
2274 PIXA *pixa;
2275 
2276  PROCNAME("pixaaGetPix");
2277 
2278  if ((pixa = pixaaGetPixa(paa, index, L_CLONE)) == NULL)
2279  return (PIX *)ERROR_PTR("pixa not retrieved", procName, NULL);
2280  if ((pix = pixaGetPix(pixa, ipix, accessflag)) == NULL)
2281  L_ERROR("pix not retrieved\n", procName);
2282  pixaDestroy(&pixa);
2283  return pix;
2284 }
2285 
2286 
2300 l_ok
2302  l_int32 *psame,
2303  l_int32 *pmaxd)
2304 {
2305 l_int32 i, n, d, maxd, same, samed;
2306 PIXA *pixa;
2307 
2308  PROCNAME("pixaaVerifyDepth");
2309 
2310  if (pmaxd) *pmaxd = 0;
2311  if (!psame)
2312  return ERROR_INT("psame not defined", procName, 1);
2313  *psame = 0;
2314  if (!paa)
2315  return ERROR_INT("paa not defined", procName, 1);
2316  if ((n = pixaaGetCount(paa, NULL)) == 0)
2317  return ERROR_INT("no pixa in paa", procName, 1);
2318 
2319  pixa = pixaaGetPixa(paa, 0, L_CLONE);
2320  pixaVerifyDepth(pixa, &same, &maxd); /* init same, maxd with first pixa */
2321  pixaDestroy(&pixa);
2322  for (i = 1; i < n; i++) {
2323  pixa = pixaaGetPixa(paa, i, L_CLONE);
2324  pixaVerifyDepth(pixa, &samed, &d);
2325  pixaDestroy(&pixa);
2326  maxd = L_MAX(maxd, d);
2327  if (!samed || maxd != d)
2328  same = 0;
2329  }
2330  *psame = same;
2331  if (pmaxd) *pmaxd = maxd;
2332  return 0;
2333 }
2334 
2335 
2350 l_ok
2352  l_int32 *psame,
2353  l_int32 *pmaxw,
2354  l_int32 *pmaxh)
2355 {
2356 l_int32 i, n, w, h, maxw, maxh, same, same2;
2357 PIXA *pixa;
2358 
2359  PROCNAME("pixaaVerifyDimensions");
2360 
2361  if (pmaxw) *pmaxw = 0;
2362  if (pmaxh) *pmaxh = 0;
2363  if (!psame)
2364  return ERROR_INT("psame not defined", procName, 1);
2365  *psame = 0;
2366  if (!paa)
2367  return ERROR_INT("paa not defined", procName, 1);
2368  if ((n = pixaaGetCount(paa, NULL)) == 0)
2369  return ERROR_INT("no pixa in paa", procName, 1);
2370 
2371  /* Init same; init maxw and maxh from first pixa */
2372  pixa = pixaaGetPixa(paa, 0, L_CLONE);
2373  pixaVerifyDimensions(pixa, &same, &maxw, &maxh);
2374  pixaDestroy(&pixa);
2375 
2376  for (i = 1; i < n; i++) {
2377  pixa = pixaaGetPixa(paa, i, L_CLONE);
2378  pixaVerifyDimensions(pixa, &same2, &w, &h);
2379  pixaDestroy(&pixa);
2380  maxw = L_MAX(maxw, w);
2381  maxh = L_MAX(maxh, h);
2382  if (!same2 || maxw != w || maxh != h)
2383  same = 0;
2384  }
2385  *psame = same;
2386  if (pmaxw) *pmaxw = maxw;
2387  if (pmaxh) *pmaxh = maxh;
2388  return 0;
2389 }
2390 
2391 
2404 l_int32
2406  l_int32 *pfull)
2407 {
2408 l_int32 i, n, full;
2409 PIXA *pixa;
2410 
2411  PROCNAME("pixaaIsFull");
2412 
2413  if (!pfull)
2414  return ERROR_INT("&full not defined", procName, 0);
2415  *pfull = 0;
2416  if (!paa)
2417  return ERROR_INT("paa not defined", procName, 0);
2418 
2419  n = pixaaGetCount(paa, NULL);
2420  full = 1;
2421  for (i = 0; i < n; i++) {
2422  pixa = pixaaGetPixa(paa, i, L_CLONE);
2423  pixaIsFull(pixa, &full, NULL);
2424  pixaDestroy(&pixa);
2425  if (!full) break;
2426  }
2427  *pfull = full;
2428  return 0;
2429 }
2430 
2431 
2432 /*---------------------------------------------------------------------*
2433  * Pixaa array modifiers *
2434  *---------------------------------------------------------------------*/
2456 l_ok
2458  PIXA *pixa)
2459 {
2460 l_int32 i, n;
2461 PIXA *pixat;
2462 
2463  PROCNAME("pixaaInitFull");
2464 
2465  if (!paa)
2466  return ERROR_INT("paa not defined", procName, 1);
2467  if (!pixa)
2468  return ERROR_INT("pixa not defined", procName, 1);
2469 
2470  n = paa->nalloc;
2471  paa->n = n;
2472  for (i = 0; i < n; i++) {
2473  pixat = pixaCopy(pixa, L_COPY);
2474  pixaaReplacePixa(paa, i, pixat);
2475  }
2476 
2477  return 0;
2478 }
2479 
2480 
2498 l_ok
2500  l_int32 index,
2501  PIXA *pixa)
2502 {
2503 
2504  PROCNAME("pixaaReplacePixa");
2505 
2506  if (!paa)
2507  return ERROR_INT("paa not defined", procName, 1);
2508  if (index < 0 || index >= paa->n)
2509  return ERROR_INT("index not valid", procName, 1);
2510  if (!pixa)
2511  return ERROR_INT("pixa not defined", procName, 1);
2512 
2513  pixaDestroy(&(paa->pixa[index]));
2514  paa->pixa[index] = pixa;
2515  return 0;
2516 }
2517 
2518 
2531 l_ok
2533 {
2534 l_int32 i, n;
2535 
2536  PROCNAME("pixaClear");
2537 
2538  if (!paa)
2539  return ERROR_INT("paa not defined", procName, 1);
2540 
2541  n = pixaaGetCount(paa, NULL);
2542  for (i = 0; i < n; i++)
2543  pixaDestroy(&paa->pixa[i]);
2544  paa->n = 0;
2545  return 0;
2546 }
2547 
2548 
2562 l_ok
2564 {
2565 l_int32 i, n, np;
2566 PIXA *pixa;
2567 
2568  PROCNAME("pixaaTruncate");
2569 
2570  if (!paa)
2571  return ERROR_INT("paa not defined", procName, 1);
2572 
2573  n = pixaaGetCount(paa, NULL);
2574  for (i = n - 1; i >= 0; i--) {
2575  pixa = pixaaGetPixa(paa, i, L_CLONE);
2576  if (!pixa) {
2577  paa->n--;
2578  continue;
2579  }
2580  np = pixaGetCount(pixa);
2581  pixaDestroy(&pixa);
2582  if (np == 0) {
2583  pixaDestroy(&paa->pixa[i]);
2584  paa->n--;
2585  } else {
2586  break;
2587  }
2588  }
2589  return 0;
2590 }
2591 
2592 
2593 
2594 /*---------------------------------------------------------------------*
2595  * Pixa serialized I/O *
2596  *---------------------------------------------------------------------*/
2609 PIXA *
2610 pixaRead(const char *filename)
2611 {
2612 FILE *fp;
2613 PIXA *pixa;
2614 
2615  PROCNAME("pixaRead");
2616 
2617 #if !HAVE_LIBPNG /* defined in environ.h and config_auto.h */
2618  return (PIXA *)ERROR_PTR("no libpng: can't read data", procName, NULL);
2619 #endif /* !HAVE_LIBPNG */
2620 
2621  if (!filename)
2622  return (PIXA *)ERROR_PTR("filename not defined", procName, NULL);
2623 
2624  if ((fp = fopenReadStream(filename)) == NULL)
2625  return (PIXA *)ERROR_PTR("stream not opened", procName, NULL);
2626  pixa = pixaReadStream(fp);
2627  fclose(fp);
2628  if (!pixa)
2629  return (PIXA *)ERROR_PTR("pixa not read", procName, NULL);
2630  return pixa;
2631 }
2632 
2633 
2647 PIXA *
2649 {
2650 l_int32 n, i, xres, yres, version;
2651 l_int32 ignore;
2652 BOXA *boxa;
2653 PIX *pix;
2654 PIXA *pixa;
2655 
2656  PROCNAME("pixaReadStream");
2657 
2658 #if !HAVE_LIBPNG /* defined in environ.h and config_auto.h */
2659  return (PIXA *)ERROR_PTR("no libpng: can't read data", procName, NULL);
2660 #endif /* !HAVE_LIBPNG */
2661 
2662  if (!fp)
2663  return (PIXA *)ERROR_PTR("stream not defined", procName, NULL);
2664 
2665  if (fscanf(fp, "\nPixa Version %d\n", &version) != 1)
2666  return (PIXA *)ERROR_PTR("not a pixa file", procName, NULL);
2667  if (version != PIXA_VERSION_NUMBER)
2668  return (PIXA *)ERROR_PTR("invalid pixa version", procName, NULL);
2669  if (fscanf(fp, "Number of pix = %d\n", &n) != 1)
2670  return (PIXA *)ERROR_PTR("not a pixa file", procName, NULL);
2671  if (n < 0)
2672  return (PIXA *)ERROR_PTR("num pix ptrs < 0", procName, NULL);
2673  if (n > MaxPixaPtrArraySize)
2674  return (PIXA *)ERROR_PTR("too many pix ptrs", procName, NULL);
2675  if (n == 0) L_INFO("the pixa is empty\n", procName);
2676 
2677  if ((boxa = boxaReadStream(fp)) == NULL)
2678  return (PIXA *)ERROR_PTR("boxa not made", procName, NULL);
2679  if ((pixa = pixaCreate(n)) == NULL) {
2680  boxaDestroy(&boxa);
2681  return (PIXA *)ERROR_PTR("pixa not made", procName, NULL);
2682  }
2683  boxaDestroy(&pixa->boxa);
2684  pixa->boxa = boxa;
2685 
2686  for (i = 0; i < n; i++) {
2687  if ((fscanf(fp, " pix[%d]: xres = %d, yres = %d\n",
2688  &ignore, &xres, &yres)) != 3) {
2689  pixaDestroy(&pixa);
2690  return (PIXA *)ERROR_PTR("res reading error", procName, NULL);
2691  }
2692  if ((pix = pixReadStreamPng(fp)) == NULL) {
2693  pixaDestroy(&pixa);
2694  return (PIXA *)ERROR_PTR("pix not read", procName, NULL);
2695  }
2696  pixSetXRes(pix, xres);
2697  pixSetYRes(pix, yres);
2698  pixaAddPix(pixa, pix, L_INSERT);
2699  }
2700  return pixa;
2701 }
2702 
2703 
2711 PIXA *
2712 pixaReadMem(const l_uint8 *data,
2713  size_t size)
2714 {
2715 FILE *fp;
2716 PIXA *pixa;
2717 
2718  PROCNAME("pixaReadMem");
2719 
2720  if (!data)
2721  return (PIXA *)ERROR_PTR("data not defined", procName, NULL);
2722  if ((fp = fopenReadFromMemory(data, size)) == NULL)
2723  return (PIXA *)ERROR_PTR("stream not opened", procName, NULL);
2724 
2725  pixa = pixaReadStream(fp);
2726  fclose(fp);
2727  if (!pixa) L_ERROR("pixa not read\n", procName);
2728  return pixa;
2729 }
2730 
2731 
2748 l_ok
2749 pixaWriteDebug(const char *fname,
2750  PIXA *pixa)
2751 {
2752  PROCNAME("pixaWriteDebug");
2753 
2754  if (LeptDebugOK) {
2755  return pixaWrite(fname, pixa);
2756  } else {
2757  L_INFO("write to named temp file %s is disabled\n", procName, fname);
2758  return 0;
2759  }
2760 }
2761 
2762 
2776 l_ok
2777 pixaWrite(const char *filename,
2778  PIXA *pixa)
2779 {
2780 l_int32 ret;
2781 FILE *fp;
2782 
2783  PROCNAME("pixaWrite");
2784 
2785 #if !HAVE_LIBPNG /* defined in environ.h and config_auto.h */
2786  return ERROR_INT("no libpng: can't write data", procName, 1);
2787 #endif /* !HAVE_LIBPNG */
2788 
2789  if (!filename)
2790  return ERROR_INT("filename not defined", procName, 1);
2791  if (!pixa)
2792  return ERROR_INT("pixa not defined", procName, 1);
2793 
2794  if ((fp = fopenWriteStream(filename, "wb")) == NULL)
2795  return ERROR_INT("stream not opened", procName, 1);
2796  ret = pixaWriteStream(fp, pixa);
2797  fclose(fp);
2798  if (ret)
2799  return ERROR_INT("pixa not written to stream", procName, 1);
2800  return 0;
2801 }
2802 
2803 
2817 l_ok
2819  PIXA *pixa)
2820 {
2821 l_int32 n, i;
2822 PIX *pix;
2823 
2824  PROCNAME("pixaWriteStream");
2825 
2826 #if !HAVE_LIBPNG /* defined in environ.h and config_auto.h */
2827  return ERROR_INT("no libpng: can't write data", procName, 1);
2828 #endif /* !HAVE_LIBPNG */
2829 
2830  if (!fp)
2831  return ERROR_INT("stream not defined", procName, 1);
2832  if (!pixa)
2833  return ERROR_INT("pixa not defined", procName, 1);
2834 
2835  n = pixaGetCount(pixa);
2836  fprintf(fp, "\nPixa Version %d\n", PIXA_VERSION_NUMBER);
2837  fprintf(fp, "Number of pix = %d\n", n);
2838  boxaWriteStream(fp, pixa->boxa);
2839  for (i = 0; i < n; i++) {
2840  if ((pix = pixaGetPix(pixa, i, L_CLONE)) == NULL)
2841  return ERROR_INT("pix not found", procName, 1);
2842  fprintf(fp, " pix[%d]: xres = %d, yres = %d\n",
2843  i, pix->xres, pix->yres);
2844  pixWriteStreamPng(fp, pix, 0.0);
2845  pixDestroy(&pix);
2846  }
2847  return 0;
2848 }
2849 
2850 
2864 l_ok
2865 pixaWriteMem(l_uint8 **pdata,
2866  size_t *psize,
2867  PIXA *pixa)
2868 {
2869 l_int32 ret;
2870 FILE *fp;
2871 
2872  PROCNAME("pixaWriteMem");
2873 
2874  if (pdata) *pdata = NULL;
2875  if (psize) *psize = 0;
2876  if (!pdata)
2877  return ERROR_INT("&data not defined", procName, 1);
2878  if (!psize)
2879  return ERROR_INT("&size not defined", procName, 1);
2880  if (!pixa)
2881  return ERROR_INT("pixa not defined", procName, 1);
2882 
2883 #if HAVE_FMEMOPEN
2884  if ((fp = open_memstream((char **)pdata, psize)) == NULL)
2885  return ERROR_INT("stream not opened", procName, 1);
2886  ret = pixaWriteStream(fp, pixa);
2887  fputc('\0', fp);
2888  fclose(fp);
2889  *psize = *psize - 1;
2890 #else
2891  L_INFO("work-around: writing to a temp file\n", procName);
2892  #ifdef _WIN32
2893  if ((fp = fopenWriteWinTempfile()) == NULL)
2894  return ERROR_INT("tmpfile stream not opened", procName, 1);
2895  #else
2896  if ((fp = tmpfile()) == NULL)
2897  return ERROR_INT("tmpfile stream not opened", procName, 1);
2898  #endif /* _WIN32 */
2899  ret = pixaWriteStream(fp, pixa);
2900  rewind(fp);
2901  *pdata = l_binaryReadStream(fp, psize);
2902  fclose(fp);
2903 #endif /* HAVE_FMEMOPEN */
2904  return ret;
2905 }
2906 
2907 
2920 PIXA *
2921 pixaReadBoth(const char *filename)
2922 {
2923 char buf[32];
2924 char *sname;
2925 PIXA *pixa;
2926 PIXAC *pac;
2927 
2928  PROCNAME("pixaReadBoth");
2929 
2930  if (!filename)
2931  return (PIXA *)ERROR_PTR("filename not defined", procName, NULL);
2932 
2933  l_getStructStrFromFile(filename, L_STR_NAME, &sname);
2934  if (!sname)
2935  return (PIXA *)ERROR_PTR("struct name not found", procName, NULL);
2936  snprintf(buf, sizeof(buf), "%s", sname);
2937  LEPT_FREE(sname);
2938 
2939  if (strcmp(buf, "Pixacomp") == 0) {
2940  if ((pac = pixacompRead(filename)) == NULL)
2941  return (PIXA *)ERROR_PTR("pac not made", procName, NULL);
2942  pixa = pixaCreateFromPixacomp(pac, L_COPY);
2943  pixacompDestroy(&pac);
2944  } else if (strcmp(buf, "Pixa") == 0) {
2945  if ((pixa = pixaRead(filename)) == NULL)
2946  return (PIXA *)ERROR_PTR("pixa not made", procName, NULL);
2947  } else {
2948  return (PIXA *)ERROR_PTR("invalid file type", procName, NULL);
2949  }
2950  return pixa;
2951 }
2952 
2953 
2954 /*---------------------------------------------------------------------*
2955  * Pixaa serialized I/O *
2956  *---------------------------------------------------------------------*/
2977 PIXAA *
2978 pixaaReadFromFiles(const char *dirname,
2979  const char *substr,
2980  l_int32 first,
2981  l_int32 nfiles)
2982 {
2983 char *fname;
2984 l_int32 i, n;
2985 PIXA *pixa;
2986 PIXAA *paa;
2987 SARRAY *sa;
2988 
2989  PROCNAME("pixaaReadFromFiles");
2990 
2991  if (!dirname)
2992  return (PIXAA *)ERROR_PTR("dirname not defined", procName, NULL);
2993 
2994  sa = getSortedPathnamesInDirectory(dirname, substr, first, nfiles);
2995  if (!sa || ((n = sarrayGetCount(sa)) == 0)) {
2996  sarrayDestroy(&sa);
2997  return (PIXAA *)ERROR_PTR("no pixa files found", procName, NULL);
2998  }
2999 
3000  paa = pixaaCreate(n);
3001  for (i = 0; i < n; i++) {
3002  fname = sarrayGetString(sa, i, L_NOCOPY);
3003  if ((pixa = pixaRead(fname)) == NULL) {
3004  L_ERROR("pixa not read for %d-th file", procName, i);
3005  continue;
3006  }
3007  pixaaAddPixa(paa, pixa, L_INSERT);
3008  }
3009 
3010  sarrayDestroy(&sa);
3011  return paa;
3012 }
3013 
3014 
3027 PIXAA *
3028 pixaaRead(const char *filename)
3029 {
3030 FILE *fp;
3031 PIXAA *paa;
3032 
3033  PROCNAME("pixaaRead");
3034 
3035 #if !HAVE_LIBPNG /* defined in environ.h and config_auto.h */
3036  return (PIXAA *)ERROR_PTR("no libpng: can't read data", procName, NULL);
3037 #endif /* !HAVE_LIBPNG */
3038 
3039  if (!filename)
3040  return (PIXAA *)ERROR_PTR("filename not defined", procName, NULL);
3041 
3042  if ((fp = fopenReadStream(filename)) == NULL)
3043  return (PIXAA *)ERROR_PTR("stream not opened", procName, NULL);
3044  paa = pixaaReadStream(fp);
3045  fclose(fp);
3046  if (!paa)
3047  return (PIXAA *)ERROR_PTR("paa not read", procName, NULL);
3048  return paa;
3049 }
3050 
3051 
3065 PIXAA *
3067 {
3068 l_int32 n, i, version;
3069 l_int32 ignore;
3070 BOXA *boxa;
3071 PIXA *pixa;
3072 PIXAA *paa;
3073 
3074  PROCNAME("pixaaReadStream");
3075 
3076 #if !HAVE_LIBPNG /* defined in environ.h and config_auto.h */
3077  return (PIXAA *)ERROR_PTR("no libpng: can't read data", procName, NULL);
3078 #endif /* !HAVE_LIBPNG */
3079 
3080  if (!fp)
3081  return (PIXAA *)ERROR_PTR("stream not defined", procName, NULL);
3082 
3083  if (fscanf(fp, "\nPixaa Version %d\n", &version) != 1)
3084  return (PIXAA *)ERROR_PTR("not a pixaa file", procName, NULL);
3085  if (version != PIXAA_VERSION_NUMBER)
3086  return (PIXAA *)ERROR_PTR("invalid pixaa version", procName, NULL);
3087  if (fscanf(fp, "Number of pixa = %d\n", &n) != 1)
3088  return (PIXAA *)ERROR_PTR("not a pixaa file", procName, NULL);
3089  if (n < 0)
3090  return (PIXAA *)ERROR_PTR("num pixa ptrs < 0", procName, NULL);
3091  if (n > MaxPixaaPtrArraySize)
3092  return (PIXAA *)ERROR_PTR("too many pixa ptrs", procName, NULL);
3093  if (n == 0) L_INFO("the pixaa is empty\n", procName);
3094 
3095  if ((paa = pixaaCreate(n)) == NULL)
3096  return (PIXAA *)ERROR_PTR("paa not made", procName, NULL);
3097  if ((boxa = boxaReadStream(fp)) == NULL) {
3098  pixaaDestroy(&paa);
3099  return (PIXAA *)ERROR_PTR("boxa not made", procName, NULL);
3100  }
3101  boxaDestroy(&paa->boxa);
3102  paa->boxa = boxa;
3103 
3104  for (i = 0; i < n; i++) {
3105  if ((fscanf(fp, "\n\n --------------- pixa[%d] ---------------\n",
3106  &ignore)) != 1) {
3107  pixaaDestroy(&paa);
3108  return (PIXAA *)ERROR_PTR("text reading", procName, NULL);
3109  }
3110  if ((pixa = pixaReadStream(fp)) == NULL) {
3111  pixaaDestroy(&paa);
3112  return (PIXAA *)ERROR_PTR("pixa not read", procName, NULL);
3113  }
3114  pixaaAddPixa(paa, pixa, L_INSERT);
3115  }
3116 
3117  return paa;
3118 }
3119 
3120 
3128 PIXAA *
3129 pixaaReadMem(const l_uint8 *data,
3130  size_t size)
3131 {
3132 FILE *fp;
3133 PIXAA *paa;
3134 
3135  PROCNAME("paaReadMem");
3136 
3137  if (!data)
3138  return (PIXAA *)ERROR_PTR("data not defined", procName, NULL);
3139  if ((fp = fopenReadFromMemory(data, size)) == NULL)
3140  return (PIXAA *)ERROR_PTR("stream not opened", procName, NULL);
3141 
3142  paa = pixaaReadStream(fp);
3143  fclose(fp);
3144  if (!paa) L_ERROR("paa not read\n", procName);
3145  return paa;
3146 }
3147 
3148 
3162 l_ok
3163 pixaaWrite(const char *filename,
3164  PIXAA *paa)
3165 {
3166 l_int32 ret;
3167 FILE *fp;
3168 
3169  PROCNAME("pixaaWrite");
3170 
3171 #if !HAVE_LIBPNG /* defined in environ.h and config_auto.h */
3172  return ERROR_INT("no libpng: can't read data", procName, 1);
3173 #endif /* !HAVE_LIBPNG */
3174 
3175  if (!filename)
3176  return ERROR_INT("filename not defined", procName, 1);
3177  if (!paa)
3178  return ERROR_INT("paa not defined", procName, 1);
3179 
3180  if ((fp = fopenWriteStream(filename, "wb")) == NULL)
3181  return ERROR_INT("stream not opened", procName, 1);
3182  ret = pixaaWriteStream(fp, paa);
3183  fclose(fp);
3184  if (ret)
3185  return ERROR_INT("paa not written to stream", procName, 1);
3186  return 0;
3187 }
3188 
3189 
3203 l_ok
3205  PIXAA *paa)
3206 {
3207 l_int32 n, i;
3208 PIXA *pixa;
3209 
3210  PROCNAME("pixaaWriteStream");
3211 
3212 #if !HAVE_LIBPNG /* defined in environ.h and config_auto.h */
3213  return ERROR_INT("no libpng: can't read data", procName, 1);
3214 #endif /* !HAVE_LIBPNG */
3215 
3216  if (!fp)
3217  return ERROR_INT("stream not defined", procName, 1);
3218  if (!paa)
3219  return ERROR_INT("paa not defined", procName, 1);
3220 
3221  n = pixaaGetCount(paa, NULL);
3222  fprintf(fp, "\nPixaa Version %d\n", PIXAA_VERSION_NUMBER);
3223  fprintf(fp, "Number of pixa = %d\n", n);
3224  boxaWriteStream(fp, paa->boxa);
3225  for (i = 0; i < n; i++) {
3226  if ((pixa = pixaaGetPixa(paa, i, L_CLONE)) == NULL)
3227  return ERROR_INT("pixa not found", procName, 1);
3228  fprintf(fp, "\n\n --------------- pixa[%d] ---------------\n", i);
3229  pixaWriteStream(fp, pixa);
3230  pixaDestroy(&pixa);
3231  }
3232  return 0;
3233 }
3234 
3235 
3249 l_ok
3250 pixaaWriteMem(l_uint8 **pdata,
3251  size_t *psize,
3252  PIXAA *paa)
3253 {
3254 l_int32 ret;
3255 FILE *fp;
3256 
3257  PROCNAME("pixaaWriteMem");
3258 
3259  if (pdata) *pdata = NULL;
3260  if (psize) *psize = 0;
3261  if (!pdata)
3262  return ERROR_INT("&data not defined", procName, 1);
3263  if (!psize)
3264  return ERROR_INT("&size not defined", procName, 1);
3265  if (!paa)
3266  return ERROR_INT("paa not defined", procName, 1);
3267 
3268 #if HAVE_FMEMOPEN
3269  if ((fp = open_memstream((char **)pdata, psize)) == NULL)
3270  return ERROR_INT("stream not opened", procName, 1);
3271  ret = pixaaWriteStream(fp, paa);
3272  fputc('\0', fp);
3273  fclose(fp);
3274  *psize = *psize - 1;
3275 #else
3276  L_INFO("work-around: writing to a temp file\n", procName);
3277  #ifdef _WIN32
3278  if ((fp = fopenWriteWinTempfile()) == NULL)
3279  return ERROR_INT("tmpfile stream not opened", procName, 1);
3280  #else
3281  if ((fp = tmpfile()) == NULL)
3282  return ERROR_INT("tmpfile stream not opened", procName, 1);
3283  #endif /* _WIN32 */
3284  ret = pixaaWriteStream(fp, paa);
3285  rewind(fp);
3286  *pdata = l_binaryReadStream(fp, psize);
3287  fclose(fp);
3288 #endif /* HAVE_FMEMOPEN */
3289  return ret;
3290 }
3291 
l_ok boxaClear(BOXA *boxa)
boxaClear()
Definition: boxbasic.c:1217
BOXA * boxaReadStream(FILE *fp)
boxaReadStream()
Definition: boxbasic.c:2161
l_ok boxaInitFull(BOXA *boxa, BOX *box)
boxaInitFull()
Definition: boxbasic.c:1180
l_ok boxaIsFull(BOXA *boxa, l_int32 *pfull)
boxaIsFull()
Definition: boxbasic.c:915
BOXA * boxaCopy(BOXA *boxa, l_int32 copyflag)
boxaCopy()
Definition: boxbasic.c:537
l_ok boxaInsertBox(BOXA *boxa, l_int32 index, BOX *box)
boxaInsertBox()
Definition: boxbasic.c:1000
void boxDestroy(BOX **pbox)
boxDestroy()
Definition: boxbasic.c:282
l_ok boxaRemoveBoxAndSave(BOXA *boxa, l_int32 index, BOX **pbox)
boxaRemoveBoxAndSave()
Definition: boxbasic.c:1072
l_ok boxaRemoveBox(BOXA *boxa, l_int32 index)
boxaRemoveBox()
Definition: boxbasic.c:1048
BOX * boxClone(BOX *box)
boxClone()
Definition: boxbasic.c:256
l_ok boxaReplaceBox(BOXA *boxa, l_int32 index, BOX *box)
boxaReplaceBox()
Definition: boxbasic.c:962
l_int32 boxaGetCount(BOXA *boxa)
boxaGetCount()
Definition: boxbasic.c:734
l_ok boxGetGeometry(BOX *box, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxGetGeometry()
Definition: boxbasic.c:313
l_ok boxaExtendArrayToSize(BOXA *boxa, size_t size)
boxaExtendArrayToSize()
Definition: boxbasic.c:696
l_ok boxaAddBox(BOXA *boxa, BOX *box, l_int32 copyflag)
boxaAddBox()
Definition: boxbasic.c:620
l_ok boxaExtendArray(BOXA *boxa)
boxaExtendArray()
Definition: boxbasic.c:671
void boxaDestroy(BOXA **pboxa)
boxaDestroy()
Definition: boxbasic.c:583
BOX * boxaGetBox(BOXA *boxa, l_int32 index, l_int32 accessflag)
boxaGetBox()
Definition: boxbasic.c:779
BOX * boxCopy(BOX *box)
boxCopy()
Definition: boxbasic.c:235
BOXA * boxaCreate(l_int32 n)
boxaCreate()
Definition: boxbasic.c:502
l_ok boxaWriteStream(FILE *fp, BOXA *boxa)
boxaWriteStream()
Definition: boxbasic.c:2299
l_ok boxaJoin(BOXA *boxad, BOXA *boxas, l_int32 istart, l_int32 iend)
boxaJoin()
Definition: boxfunc1.c:2537
l_ok boxaGetExtent(BOXA *boxa, l_int32 *pw, l_int32 *ph, BOX **pbox)
boxaGetExtent()
Definition: boxfunc4.c:953
l_int32 pixcmapGetCount(const PIXCMAP *cmap)
pixcmapGetCount()
Definition: colormap.c:708
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:478
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:194
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:366
l_int32 numaGetCount(NUMA *na)
numaGetCount()
Definition: numabasic.c:658
l_ok numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition: numabasic.c:754
NUMA * numaSort(NUMA *naout, NUMA *nain, l_int32 sortorder)
numaSort()
Definition: numafunc1.c:2650
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:621
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1113
char * pixGetText(PIX *pix)
pixGetText()
Definition: pix1.c:1512
l_ok pixSetText(PIX *pix, const char *textstring)
pixSetText()
Definition: pix1.c:1536
PIX * pixCopy(PIX *pixd, const PIX *pixs)
pixCopy()
Definition: pix1.c:705
l_ok pixCopyColormap(PIX *pixd, const PIX *pixs)
pixCopyColormap()
Definition: pix1.c:816
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:315
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:593
void ** pixGetLinePtrs(PIX *pix, l_int32 *psize)
pixGetLinePtrs()
Definition: pix1.c:1949
l_ok pixClearAll(PIX *pix)
pixClearAll()
Definition: pix2.c:789
l_ok pixSetAll(PIX *pix)
pixSetAll()
Definition: pix2.c:817
l_ok pixSetAllArbitrary(PIX *pix, l_uint32 val)
pixSetAllArbitrary()
Definition: pix2.c:951
PIX * pixClipRectangle(PIX *pixs, BOX *box, BOX **pboxc)
pixClipRectangle()
Definition: pix5.c:1026
l_ok pixClipToForeground(PIX *pixs, PIX **ppixd, BOX **pbox)
pixClipToForeground()
Definition: pix5.c:1784
@ L_COPY
Definition: pix.h:712
@ L_CLONE
Definition: pix.h:713
@ L_COPY_CLONE
Definition: pix.h:714
@ L_NOCOPY
Definition: pix.h:710
@ L_INSERT
Definition: pix.h:711
@ L_CHOOSE_CONSECUTIVE
Definition: pix.h:982
@ L_CHOOSE_SKIP_BY
Definition: pix.h:983
#define PIXA_VERSION_NUMBER
Definition: pix.h:450
#define PIXAA_VERSION_NUMBER
Definition: pix.h:449
#define PIX_SRC
Definition: pix.h:330
@ L_SORT_DECREASING
Definition: pix.h:730
PIXAA * pixaaCreate(l_int32 n)
pixaaCreate()
Definition: pixabasic.c:1852
l_ok pixaAddPix(PIXA *pixa, PIX *pix, l_int32 copyflag)
pixaAddPix()
Definition: pixabasic.c:506
l_ok pixaaReplacePixa(PIXAA *paa, l_int32 index, PIXA *pixa)
pixaaReplacePixa()
Definition: pixabasic.c:2499
void pixaDestroy(PIXA **ppixa)
pixaDestroy()
Definition: pixabasic.c:412
static l_int32 pixaExtendArray(PIXA *pixa)
pixaExtendArray()
Definition: pixabasic.c:586
l_ok pixaaWriteMem(l_uint8 **pdata, size_t *psize, PIXAA *paa)
pixaaWriteMem()
Definition: pixabasic.c:3250
l_ok pixaVerifyDepth(PIXA *pixa, l_int32 *psame, l_int32 *pmaxd)
pixaVerifyDepth()
Definition: pixabasic.c:960
l_ok pixaaInitFull(PIXAA *paa, PIXA *pixa)
pixaaInitFull()
Definition: pixabasic.c:2457
l_ok pixaCountText(PIXA *pixa, l_int32 *pntext)
pixaCountText()
Definition: pixabasic.c:1107
l_int32 pixaaIsFull(PIXAA *paa, l_int32 *pfull)
pixaaIsFull()
Definition: pixabasic.c:2405
l_ok pixaExtendArrayToSize(PIXA *pixa, size_t size)
pixaExtendArrayToSize()
Definition: pixabasic.c:612
l_ok pixaChangeRefcount(PIXA *pixa, l_int32 delta)
pixaChangeRefcount()
Definition: pixabasic.c:669
PIXAA * pixaaReadStream(FILE *fp)
pixaaReadStream()
Definition: pixabasic.c:3066
l_ok pixaRemovePix(PIXA *pixa, l_int32 index)
pixaRemovePix()
Definition: pixabasic.c:1423
l_ok pixaaAddBox(PIXAA *paa, BOX *box, l_int32 copyflag)
pixaaAddBox()
Definition: pixabasic.c:2122
l_ok pixaWriteStream(FILE *fp, PIXA *pixa)
pixaWriteStream()
Definition: pixabasic.c:2818
PIXA * pixaReadBoth(const char *filename)
pixaReadBoth()
Definition: pixabasic.c:2921
l_ok pixaaTruncate(PIXAA *paa)
pixaaTruncate()
Definition: pixabasic.c:2563
l_ok pixaaAddPix(PIXAA *paa, l_int32 index, PIX *pix, BOX *box, l_int32 copyflag)
pixaaAddPix()
Definition: pixabasic.c:2083
BOX * pixaGetBox(PIXA *pixa, l_int32 index, l_int32 accesstype)
pixaGetBox()
Definition: pixabasic.c:816
static l_int32 pixaaExtendArray(PIXAA *paa)
pixaaExtendArray()
Definition: pixabasic.c:2048
l_int32 pixaGetBoxaCount(PIXA *pixa)
pixaGetBoxaCount()
Definition: pixabasic.c:784
PIXA * pixaInterleave(PIXA *pixa1, PIXA *pixa2, l_int32 copyflag)
pixaInterleave()
Definition: pixabasic.c:1729
l_ok pixaSetText(PIXA *pixa, const char *text, SARRAY *sa)
pixaSetText()
Definition: pixabasic.c:1155
l_ok pixaaAddPixa(PIXAA *paa, PIXA *pixa, l_int32 copyflag)
pixaaAddPixa()
Definition: pixabasic.c:1998
void *** pixaGetLinePtrs(PIXA *pixa, l_int32 *psize)
pixaGetLinePtrs()
Definition: pixabasic.c:1214
PIXA * pixaCreate(l_int32 n)
pixaCreate()
Definition: pixabasic.c:167
l_ok pixaRemovePixAndSave(PIXA *pixa, l_int32 index, PIX **ppix, BOX **pbox)
pixaRemovePixAndSave()
Definition: pixabasic.c:1477
PIXA * pixaSplitPix(PIX *pixs, l_int32 nx, l_int32 ny, l_int32 borderwidth, l_uint32 bordercolor)
pixaSplitPix()
Definition: pixabasic.c:350
l_ok pixaGetPixDimensions(PIXA *pixa, l_int32 index, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixaGetPixDimensions()
Definition: pixabasic.c:726
PIX ** pixaGetPixArray(PIXA *pixa)
pixaGetPixArray()
Definition: pixabasic.c:935
PIXA * pixaRead(const char *filename)
pixaRead()
Definition: pixabasic.c:2610
l_ok pixaaJoin(PIXAA *paad, PIXAA *paas, l_int32 istart, l_int32 iend)
pixaaJoin()
Definition: pixabasic.c:1794
l_ok pixaRemoveSelected(PIXA *pixa, NUMA *naindex)
pixaRemoveSelected()
Definition: pixabasic.c:1531
PIXA * pixaCopy(PIXA *pixa, l_int32 copyflag)
pixaCopy()
Definition: pixabasic.c:453
l_ok pixaReplacePix(PIXA *pixa, l_int32 index, PIX *pix, BOX *box)
pixaReplacePix()
Definition: pixabasic.c:1320
l_int32 pixaGetCount(PIXA *pixa)
pixaGetCount()
Definition: pixabasic.c:650
l_ok pixaWrite(const char *filename, PIXA *pixa)
pixaWrite()
Definition: pixabasic.c:2777
l_ok pixaaVerifyDimensions(PIXAA *paa, l_int32 *psame, l_int32 *pmaxw, l_int32 *pmaxh)
pixaaVerifyDimensions()
Definition: pixabasic.c:2351
l_ok pixaAddBox(PIXA *pixa, BOX *box, l_int32 copyflag)
pixaAddBox()
Definition: pixabasic.c:555
l_ok pixaWriteMem(l_uint8 **pdata, size_t *psize, PIXA *pixa)
pixaWriteMem()
Definition: pixabasic.c:2865
static const size_t InitialPtrArraySize
Definition: pixabasic.c:146
PIXA * pixaReadMem(const l_uint8 *data, size_t size)
pixaReadMem()
Definition: pixabasic.c:2712
l_ok pixaWriteStreamInfo(FILE *fp, PIXA *pixa)
pixaWriteStreamInfo()
Definition: pixabasic.c:1262
l_ok pixaIsFull(PIXA *pixa, l_int32 *pfullpa, l_int32 *pfullba)
pixaIsFull()
Definition: pixabasic.c:1057
PIXAA * pixaaReadFromFiles(const char *dirname, const char *substr, l_int32 first, l_int32 nfiles)
pixaaReadFromFiles()
Definition: pixabasic.c:2978
PIXAA * pixaaCreateFromPixa(PIXA *pixa, l_int32 n, l_int32 type, l_int32 copyflag)
pixaaCreateFromPixa()
Definition: pixabasic.c:1895
PIXAA * pixaaReadMem(const l_uint8 *data, size_t size)
pixaaReadMem()
Definition: pixabasic.c:3129
l_ok pixaInitFull(PIXA *pixa, PIX *pix, BOX *box)
pixaInitFull()
Definition: pixabasic.c:1593
PIXA * pixaReadStream(FILE *fp)
pixaReadStream()
Definition: pixabasic.c:2648
l_ok pixaVerifyDimensions(PIXA *pixa, l_int32 *psame, l_int32 *pmaxw, l_int32 *pmaxh)
pixaVerifyDimensions()
Definition: pixabasic.c:1006
l_ok pixaaWriteStream(FILE *fp, PIXAA *paa)
pixaaWriteStream()
Definition: pixabasic.c:3204
BOXA * pixaGetBoxa(PIXA *pixa, l_int32 accesstype)
pixaGetBoxa()
Definition: pixabasic.c:760
BOXA * pixaaGetBoxa(PIXAA *paa, l_int32 accesstype)
pixaaGetBoxa()
Definition: pixabasic.c:2244
l_ok pixaGetBoxGeometry(PIXA *pixa, l_int32 index, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
pixaGetBoxGeometry()
Definition: pixabasic.c:854
l_ok pixaWriteDebug(const char *fname, PIXA *pixa)
pixaWriteDebug()
Definition: pixabasic.c:2749
PIXA * pixaCreateFromBoxa(PIX *pixs, BOXA *boxa, l_int32 start, l_int32 num, l_int32 *pcropwarn)
pixaCreateFromBoxa()
Definition: pixabasic.c:272
void pixaaDestroy(PIXAA **ppaa)
pixaaDestroy()
Definition: pixabasic.c:1957
l_ok pixaaClear(PIXAA *paa)
pixaaClear()
Definition: pixabasic.c:2532
l_ok pixaaVerifyDepth(PIXAA *paa, l_int32 *psame, l_int32 *pmaxd)
pixaaVerifyDepth()
Definition: pixabasic.c:2301
l_int32 pixaaGetCount(PIXAA *paa, NUMA **pna)
pixaaGetCount()
Definition: pixabasic.c:2157
l_ok pixaJoin(PIXA *pixad, PIXA *pixas, l_int32 istart, l_int32 iend)
pixaJoin()
Definition: pixabasic.c:1673
PIX * pixaaGetPix(PIXAA *paa, l_int32 index, l_int32 ipix, l_int32 accessflag)
pixaaGetPix()
Definition: pixabasic.c:2268
PIXA * pixaaGetPixa(PIXAA *paa, l_int32 index, l_int32 accesstype)
pixaaGetPixa()
Definition: pixabasic.c:2206
PIX * pixaGetPix(PIXA *pixa, l_int32 index, l_int32 accesstype)
pixaGetPix()
Definition: pixabasic.c:691
l_ok pixaInsertPix(PIXA *pixa, l_int32 index, PIX *pixs, BOX *box)
pixaInsertPix()
Definition: pixabasic.c:1370
PIXAA * pixaaRead(const char *filename)
pixaaRead()
Definition: pixabasic.c:3028
l_ok pixaSetBoxa(PIXA *pixa, BOXA *boxa, l_int32 accesstype)
pixaSetBoxa()
Definition: pixabasic.c:896
l_ok pixaClear(PIXA *pixa)
pixaClear()
Definition: pixabasic.c:1635
l_ok pixaaWrite(const char *filename, PIXAA *paa)
pixaaWrite()
Definition: pixabasic.c:3163
PIXA * pixaCreateFromPix(PIX *pixs, l_int32 n, l_int32 cellw, l_int32 cellh)
pixaCreateFromPix()
Definition: pixabasic.c:206
void pixacompDestroy(PIXAC **ppixac)
pixacompDestroy()
Definition: pixcomp.c:878
PIXA * pixaCreateFromPixacomp(PIXAC *pixac, l_int32 accesstype)
pixaCreateFromPixacomp()
Definition: pixcomp.c:1495
PIXAC * pixacompRead(const char *filename)
pixacompRead()
Definition: pixcomp.c:1668
l_ok pixWriteStreamPng(FILE *fp, PIX *pix, l_float32 gamma)
pixWriteStreamPng()
Definition: pngio.c:1072
PIX * pixReadStreamPng(FILE *fp)
pixReadStreamPng()
Definition: pngio.c:187
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
char * sarrayGetString(SARRAY *sa, l_int32 index, l_int32 copyflag)
sarrayGetString()
Definition: sarray1.c:703
l_int32 sarrayGetCount(SARRAY *sa)
sarrayGetCount()
Definition: sarray1.c:643
void sarrayDestroy(SARRAY **psa)
sarrayDestroy()
Definition: sarray1.c:362
SARRAY * getSortedPathnamesInDirectory(const char *dirname, const char *substr, l_int32 first, l_int32 nfiles)
getSortedPathnamesInDirectory()
Definition: sarray1.c:1848
l_int32 l_getStructStrFromFile(const char *filename, l_int32 field, char **pstr)
l_getStructStrFromFile()
Definition: stringcode.c:528
@ L_STR_NAME
Definition: stringcode.h:56
Definition: pix.h:481
Definition: pix.h:492
l_int32 n
Definition: pix.h:493
struct Box ** box
Definition: pix.h:496
Definition: array.h:71
Definition: pix.h:139
l_int32 xres
Definition: pix.h:146
l_int32 yres
Definition: pix.h:148
Definition: pix.h:654
Definition: pix.h:456
struct Pix ** pix
Definition: pix.h:460
struct Boxa * boxa
Definition: pix.h:461
l_uint32 refcount
Definition: pix.h:459
l_int32 nalloc
Definition: pix.h:458
l_int32 n
Definition: pix.h:457
Definition: pix.h:467
l_int32 nalloc
Definition: pix.h:469
l_int32 n
Definition: pix.h:468
struct Pixa ** pixa
Definition: pix.h:470
struct Boxa * boxa
Definition: pix.h:471
Definition: array.h:127
l_uint8 * l_binaryReadStream(FILE *fp, size_t *pnbytes)
l_binaryReadStream()
Definition: utils2.c:1402
FILE * fopenReadFromMemory(const l_uint8 *data, size_t size)
fopenReadFromMemory()
Definition: utils2.c:2009
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1975
void * reallocNew(void **pindata, size_t oldsize, size_t newsize)
reallocNew()
Definition: utils2.c:1302
FILE * fopenWriteWinTempfile(void)
fopenWriteWinTempfile()
Definition: utils2.c:2055
FILE * fopenReadStream(const char *filename)
fopenReadStream()
Definition: utils2.c:1932