Leptonica  1.82.0
Image processing and image analysis suite
boxbasic.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 
134 #ifdef HAVE_CONFIG_H
135 #include <config_auto.h>
136 #endif /* HAVE_CONFIG_H */
137 
138 #include <string.h>
139 #include "allheaders.h"
140 
141  /* Bounds on array sizes */
142 static const size_t MaxBoxaPtrArraySize = 10000000;
143 static const size_t MaxBoxaaPtrArraySize = 1000000;
144 static const size_t InitialPtrArraySize = 20;
146 /*---------------------------------------------------------------------*
147  * Box creation, destruction and copy *
148  *---------------------------------------------------------------------*/
171 BOX *
172 boxCreate(l_int32 x,
173  l_int32 y,
174  l_int32 w,
175  l_int32 h)
176 {
177 BOX *box;
178 
179  PROCNAME("boxCreate");
180 
181  if (w < 0 || h < 0)
182  return (BOX *)ERROR_PTR("w and h not both >= 0", procName, NULL);
183  if (x < 0) { /* take part in +quad */
184  w = w + x;
185  x = 0;
186  if (w <= 0)
187  return (BOX *)ERROR_PTR("x < 0 and box off +quad", procName, NULL);
188  }
189  if (y < 0) { /* take part in +quad */
190  h = h + y;
191  y = 0;
192  if (h <= 0)
193  return (BOX *)ERROR_PTR("y < 0 and box off +quad", procName, NULL);
194  }
195 
196  box = (BOX *)LEPT_CALLOC(1, sizeof(BOX));
197  boxSetGeometry(box, x, y, w, h);
198  box->refcount = 1;
199  return box;
200 }
201 
202 
214 BOX *
215 boxCreateValid(l_int32 x,
216  l_int32 y,
217  l_int32 w,
218  l_int32 h)
219 {
220  PROCNAME("boxCreateValid");
221 
222  if (w <= 0 || h <= 0)
223  return (BOX *)ERROR_PTR("w and h not both > 0", procName, NULL);
224  return boxCreate(x, y, w, h);
225 }
226 
227 
234 BOX *
236 {
237 BOX *boxc;
238 
239  PROCNAME("boxCopy");
240 
241  if (!box)
242  return (BOX *)ERROR_PTR("box not defined", procName, NULL);
243 
244  boxc = boxCreate(box->x, box->y, box->w, box->h);
245  return boxc;
246 }
247 
248 
255 BOX *
257 {
258 
259  PROCNAME("boxClone");
260 
261  if (!box)
262  return (BOX *)ERROR_PTR("box not defined", procName, NULL);
263 
264  boxChangeRefcount(box, 1);
265  return box;
266 }
267 
268 
281 void
283 {
284 BOX *box;
285 
286  PROCNAME("boxDestroy");
287 
288  if (pbox == NULL) {
289  L_WARNING("ptr address is null!\n", procName);
290  return;
291  }
292  if ((box = *pbox) == NULL)
293  return;
294 
295  boxChangeRefcount(box, -1);
296  if (boxGetRefcount(box) <= 0)
297  LEPT_FREE(box);
298  *pbox = NULL;
299 }
300 
301 
302 /*---------------------------------------------------------------------*
303  * Box accessors *
304  *---------------------------------------------------------------------*/
312 l_ok
314  l_int32 *px,
315  l_int32 *py,
316  l_int32 *pw,
317  l_int32 *ph)
318 {
319  PROCNAME("boxGetGeometry");
320 
321  if (px) *px = 0;
322  if (py) *py = 0;
323  if (pw) *pw = 0;
324  if (ph) *ph = 0;
325  if (!box)
326  return ERROR_INT("box not defined", procName, 1);
327  if (px) *px = box->x;
328  if (py) *py = box->y;
329  if (pw) *pw = box->w;
330  if (ph) *ph = box->h;
331  return 0;
332 }
333 
334 
342 l_ok
344  l_int32 x,
345  l_int32 y,
346  l_int32 w,
347  l_int32 h)
348 {
349  PROCNAME("boxSetGeometry");
350 
351  if (!box)
352  return ERROR_INT("box not defined", procName, 1);
353  if (x != -1) box->x = x;
354  if (y != -1) box->y = y;
355  if (w != -1) box->w = w;
356  if (h != -1) box->h = h;
357  return 0;
358 }
359 
360 
373 l_ok
375  l_int32 *pl,
376  l_int32 *pr,
377  l_int32 *pt,
378  l_int32 *pb)
379 {
380 l_int32 x, y, w, h;
381 
382  PROCNAME("boxGetSideLocations");
383 
384  if (pl) *pl = 0;
385  if (pr) *pr = 0;
386  if (pt) *pt = 0;
387  if (pb) *pb = 0;
388  if (!box)
389  return ERROR_INT("box not defined", procName, 1);
390 
391  boxGetGeometry(box, &x, &y, &w, &h);
392  if (pl) *pl = x;
393  if (pr) *pr = x + w - 1;
394  if (pt) *pt = y;
395  if (pb) *pb = y + h - 1;
396  return 0;
397 }
398 
399 
407 l_ok
409  l_int32 l,
410  l_int32 r,
411  l_int32 t,
412  l_int32 b)
413 {
414 l_int32 x, y, w, h;
415 
416  PROCNAME("boxSetSideLocations");
417 
418  if (!box)
419  return ERROR_INT("box not defined", procName, 1);
420  x = (l != -1) ? l : box->x;
421  w = (r != -1) ? r - x + 1 : box->x + box->w - x;
422  y = (t != -1) ? t : box->y;
423  h = (b != -1) ? b - y + 1 : box->y + box->h - y;
424  boxSetGeometry(box, x, y, w, h);
425  return 0;
426 }
427 
428 
435 l_int32
437 {
438  PROCNAME("boxGetRefcount");
439 
440  if (!box)
441  return ERROR_INT("box not defined", procName, UNDEF);
442 
443  return box->refcount;
444 }
445 
453 l_ok
455  l_int32 delta)
456 {
457  PROCNAME("boxChangeRefcount");
458 
459  if (!box)
460  return ERROR_INT("box not defined", procName, 1);
461 
462  box->refcount += delta;
463  return 0;
464 }
465 
466 
474 l_ok
476  l_int32 *pvalid)
477 {
478  PROCNAME("boxIsValid");
479 
480  if (!pvalid)
481  return ERROR_INT("&valid not defined", procName, 1);
482  *pvalid = 0;
483  if (!box)
484  return ERROR_INT("box not defined", procName, 1);
485 
486  if (box->w > 0 && box->h > 0)
487  *pvalid = 1;
488  return 0;
489 }
490 
491 
492 /*---------------------------------------------------------------------*
493  * Boxa creation, destruction, copy, extension *
494  *---------------------------------------------------------------------*/
501 BOXA *
502 boxaCreate(l_int32 n)
503 {
504 BOXA *boxa;
505 
506  PROCNAME("boxaCreate");
507 
508  if (n <= 0 || n > MaxBoxaPtrArraySize)
510 
511  boxa = (BOXA *)LEPT_CALLOC(1, sizeof(BOXA));
512  boxa->n = 0;
513  boxa->nalloc = n;
514  boxa->refcount = 1;
515  if ((boxa->box = (BOX **)LEPT_CALLOC(n, sizeof(BOX *))) == NULL) {
516  boxaDestroy(&boxa);
517  return (BOXA *)ERROR_PTR("boxa ptrs not made", procName, NULL);
518  }
519  return boxa;
520 }
521 
522 
536 BOXA *
538  l_int32 copyflag)
539 {
540 l_int32 i;
541 BOX *boxc;
542 BOXA *boxac;
543 
544  PROCNAME("boxaCopy");
545 
546  if (!boxa)
547  return (BOXA *)ERROR_PTR("boxa not defined", procName, NULL);
548 
549  if (copyflag == L_CLONE) {
550  boxa->refcount++;
551  return boxa;
552  }
553 
554  if (copyflag != L_COPY && copyflag != L_COPY_CLONE)
555  return (BOXA *)ERROR_PTR("invalid copyflag", procName, NULL);
556 
557  if ((boxac = boxaCreate(boxa->nalloc)) == NULL)
558  return (BOXA *)ERROR_PTR("boxac not made", procName, NULL);
559  for (i = 0; i < boxa->n; i++) {
560  if (copyflag == L_COPY)
561  boxc = boxaGetBox(boxa, i, L_COPY);
562  else /* copy-clone */
563  boxc = boxaGetBox(boxa, i, L_CLONE);
564  boxaAddBox(boxac, boxc, L_INSERT);
565  }
566  return boxac;
567 }
568 
569 
582 void
584 {
585 l_int32 i;
586 BOXA *boxa;
587 
588  PROCNAME("boxaDestroy");
589 
590  if (pboxa == NULL) {
591  L_WARNING("ptr address is null!\n", procName);
592  return;
593  }
594 
595  if ((boxa = *pboxa) == NULL)
596  return;
597 
598  /* Decrement the ref count. If it is 0, destroy the boxa. */
599  boxa->refcount--;
600  if (boxa->refcount <= 0) {
601  for (i = 0; i < boxa->n; i++)
602  boxDestroy(&boxa->box[i]);
603  LEPT_FREE(boxa->box);
604  LEPT_FREE(boxa);
605  }
606 
607  *pboxa = NULL;
608 }
609 
610 
619 l_ok
621  BOX *box,
622  l_int32 copyflag)
623 {
624 l_int32 n;
625 BOX *boxc;
626 
627  PROCNAME("boxaAddBox");
628 
629  if (!boxa)
630  return ERROR_INT("boxa not defined", procName, 1);
631  if (!box)
632  return ERROR_INT("box not defined", procName, 1);
633 
634  if (copyflag == L_INSERT)
635  boxc = box;
636  else if (copyflag == L_COPY)
637  boxc = boxCopy(box);
638  else if (copyflag == L_CLONE)
639  boxc = boxClone(box);
640  else
641  return ERROR_INT("invalid copyflag", procName, 1);
642  if (!boxc)
643  return ERROR_INT("boxc not made", procName, 1);
644 
645  n = boxaGetCount(boxa);
646  if (n >= boxa->nalloc) {
647  if (boxaExtendArray(boxa)) {
648  if (copyflag != L_INSERT)
649  boxDestroy(&boxc);
650  return ERROR_INT("extension failed", procName, 1);
651  }
652  }
653  boxa->box[n] = boxc;
654  boxa->n++;
655  return 0;
656 }
657 
658 
670 l_ok
672 {
673  PROCNAME("boxaExtendArray");
674 
675  if (!boxa)
676  return ERROR_INT("boxa not defined", procName, 1);
677 
678  return boxaExtendArrayToSize(boxa, 2 * boxa->nalloc);
679 }
680 
681 
695 l_ok
697  size_t size)
698 {
699 size_t oldsize, newsize;
700 
701  PROCNAME("boxaExtendArrayToSize");
702 
703  if (!boxa)
704  return ERROR_INT("boxa not defined", procName, 1);
705  if (boxa->nalloc > MaxBoxaPtrArraySize) /* belt & suspenders */
706  return ERROR_INT("boxa has too many ptrs", procName, 1);
707  if (size > MaxBoxaPtrArraySize)
708  return ERROR_INT("size > 10M box ptrs; too large", procName, 1);
709  if (size <= boxa->nalloc) {
710  L_INFO("size too small; no extension\n", procName);
711  return 0;
712  }
713 
714  oldsize = boxa->nalloc * sizeof(BOX *);
715  newsize = size * sizeof(BOX *);
716  if ((boxa->box = (BOX **)reallocNew((void **)&boxa->box,
717  oldsize, newsize)) == NULL)
718  return ERROR_INT("new ptr array not returned", procName, 1);
719  boxa->nalloc = size;
720  return 0;
721 }
722 
723 
724 /*---------------------------------------------------------------------*
725  * Boxa accessors *
726  *---------------------------------------------------------------------*/
733 l_int32
735 {
736  PROCNAME("boxaGetCount");
737 
738  if (!boxa)
739  return ERROR_INT("boxa not defined", procName, 0);
740  return boxa->n;
741 }
742 
743 
750 l_int32
752 {
753 l_int32 n, i, w, h, count;
754 
755  PROCNAME("boxaGetValidCount");
756 
757  if (!boxa)
758  return ERROR_INT("boxa not defined", procName, 0);
759 
760  n = boxaGetCount(boxa);
761  for (i = 0, count = 0; i < n; i++) {
762  boxaGetBoxGeometry(boxa, i, NULL, NULL, &w, &h);
763  if (w > 0 && h > 0)
764  count++;
765  }
766  return count;
767 }
768 
769 
778 BOX *
780  l_int32 index,
781  l_int32 accessflag)
782 {
783  PROCNAME("boxaGetBox");
784 
785  if (!boxa)
786  return (BOX *)ERROR_PTR("boxa not defined", procName, NULL);
787  if (index < 0 || index >= boxa->n)
788  return (BOX *)ERROR_PTR("index not valid", procName, NULL);
789 
790  if (accessflag == L_COPY)
791  return boxCopy(boxa->box[index]);
792  else if (accessflag == L_CLONE)
793  return boxClone(boxa->box[index]);
794  else
795  return (BOX *)ERROR_PTR("invalid accessflag", procName, NULL);
796 }
797 
798 
817 BOX *
819  l_int32 index,
820  l_int32 accessflag)
821 {
822 l_int32 w, h;
823 BOX *box;
824 
825  PROCNAME("boxaGetValidBox");
826 
827  if (!boxa)
828  return (BOX *)ERROR_PTR("boxa not defined", procName, NULL);
829 
830  if ((box = boxaGetBox(boxa, index, accessflag)) == NULL)
831  return (BOX *)ERROR_PTR("box not returned", procName, NULL);
832  boxGetGeometry(box, NULL, NULL, &w, &h);
833  if (w <= 0 || h <= 0) /* not valid, but not necessarily an error */
834  boxDestroy(&box);
835  return box;
836 }
837 
838 
845 NUMA *
847 {
848 l_int32 i, n, w, h;
849 NUMA *na;
850 
851  PROCNAME("boxaFindInvalidBoxes");
852 
853  if (!boxa)
854  return (NUMA *)ERROR_PTR("boxa not defined", procName, NULL);
855 
856  n = boxaGetCount(boxa);
857  if (boxaGetValidCount(boxa) == n)
858  return NULL;
859 
860  na = numaMakeConstant(0, n);
861  for (i = 0; i < n; i++) {
862  boxaGetBoxGeometry(boxa, i, NULL, NULL, &w, &h);
863  if (w == 0 || h == 0)
864  numaSetValue(na, i, 1);
865  }
866  return na;
867 }
868 
869 
878 l_ok
880  l_int32 index,
881  l_int32 *px,
882  l_int32 *py,
883  l_int32 *pw,
884  l_int32 *ph)
885 {
886 BOX *box;
887 
888  PROCNAME("boxaGetBoxGeometry");
889 
890  if (px) *px = 0;
891  if (py) *py = 0;
892  if (pw) *pw = 0;
893  if (ph) *ph = 0;
894  if (!boxa)
895  return ERROR_INT("boxa not defined", procName, 1);
896  if (index < 0 || index >= boxa->n)
897  return ERROR_INT("index not valid", procName, 1);
898 
899  if ((box = boxaGetBox(boxa, index, L_CLONE)) == NULL)
900  return ERROR_INT("box not found!", procName, 1);
901  boxGetGeometry(box, px, py, pw, ph);
902  boxDestroy(&box);
903  return 0;
904 }
905 
906 
914 l_ok
916  l_int32 *pfull)
917 {
918 l_int32 i, n, full;
919 BOX *box;
920 
921  PROCNAME("boxaIsFull");
922 
923  if (!pfull)
924  return ERROR_INT("&full not defined", procName, 1);
925  *pfull = 0;
926  if (!boxa)
927  return ERROR_INT("boxa not defined", procName, 1);
928 
929  n = boxaGetCount(boxa);
930  full = 1;
931  for (i = 0; i < n; i++) {
932  if ((box = boxaGetBox(boxa, i, L_CLONE)) == NULL) {
933  full = 0;
934  break;
935  }
936  boxDestroy(&box);
937  }
938  *pfull = full;
939  return 0;
940 }
941 
942 
943 /*---------------------------------------------------------------------*
944  * Boxa array modifiers *
945  *---------------------------------------------------------------------*/
961 l_ok
963  l_int32 index,
964  BOX *box)
965 {
966  PROCNAME("boxaReplaceBox");
967 
968  if (!boxa)
969  return ERROR_INT("boxa not defined", procName, 1);
970  if (index < 0 || index >= boxa->n)
971  return ERROR_INT("index not valid", procName, 1);
972  if (!box)
973  return ERROR_INT("box not defined", procName, 1);
974 
975  boxDestroy(&(boxa->box[index]));
976  boxa->box[index] = box;
977  return 0;
978 }
979 
980 
999 l_ok
1001  l_int32 index,
1002  BOX *box)
1003 {
1004 l_int32 i, n;
1005 BOX **array;
1006 
1007  PROCNAME("boxaInsertBox");
1008 
1009  if (!boxa)
1010  return ERROR_INT("boxa not defined", procName, 1);
1011  n = boxaGetCount(boxa);
1012  if (index < 0 || index > n) {
1013  L_ERROR("index %d not in [0,...,%d]\n", procName, index, n);
1014  return 1;
1015  }
1016  if (!box)
1017  return ERROR_INT("box not defined", procName, 1);
1018 
1019  if (n >= boxa->nalloc) {
1020  if (boxaExtendArray(boxa))
1021  return ERROR_INT("extension failed", procName, 1);
1022  }
1023  array = boxa->box;
1024  boxa->n++;
1025  for (i = n; i > index; i--)
1026  array[i] = array[i - 1];
1027  array[index] = box;
1028  return 0;
1029 }
1030 
1031 
1047 l_ok
1049  l_int32 index)
1050 {
1051  return boxaRemoveBoxAndSave(boxa, index, NULL);
1052 }
1053 
1054 
1071 l_ok
1073  l_int32 index,
1074  BOX **pbox)
1075 {
1076 l_int32 i, n;
1077 BOX **array;
1078 
1079  PROCNAME("boxaRemoveBoxAndSave");
1080 
1081  if (pbox) *pbox = NULL;
1082  if (!boxa)
1083  return ERROR_INT("boxa not defined", procName, 1);
1084  n = boxaGetCount(boxa);
1085  if (index < 0 || index >= n) {
1086  L_ERROR("index %d not in [0,...,%d]\n", procName, index, n - 1);
1087  return 1;
1088  }
1089 
1090  if (pbox)
1091  *pbox = boxaGetBox(boxa, index, L_CLONE);
1092  array = boxa->box;
1093  boxDestroy(&array[index]);
1094  for (i = index + 1; i < n; i++)
1095  array[i - 1] = array[i];
1096  array[n - 1] = NULL;
1097  boxa->n--;
1098 
1099  return 0;
1100 }
1101 
1102 
1115 BOXA *
1117  l_int32 copyflag)
1118 {
1119 l_int32 i, n;
1120 BOX *box;
1121 BOXA *boxad;
1122 
1123  PROCNAME("boxaSaveValid");
1124 
1125  if (!boxas)
1126  return (BOXA *)ERROR_PTR("boxas not defined", procName, NULL);
1127  if (copyflag != L_COPY && copyflag != L_CLONE)
1128  return (BOXA *)ERROR_PTR("invalid copyflag", procName, NULL);
1129 
1130  n = boxaGetCount(boxas);
1131  boxad = boxaCreate(n);
1132  for (i = 0; i < n; i++) {
1133  if ((box = boxaGetValidBox(boxas, i, copyflag)) != NULL)
1134  boxaAddBox(boxad, box, L_INSERT);
1135  }
1136 
1137  return boxad;
1138 }
1139 
1140 
1179 l_ok
1181  BOX *box)
1182 {
1183 l_int32 i, n;
1184 BOX *boxt;
1185 
1186  PROCNAME("boxaInitFull");
1187 
1188  if (!boxa)
1189  return ERROR_INT("boxa not defined", procName, 1);
1190 
1191  n = boxa->nalloc;
1192  boxa->n = n;
1193  for (i = 0; i < n; i++) {
1194  if (box)
1195  boxt = boxCopy(box);
1196  else
1197  boxt = boxCreate(0, 0, 0, 0);
1198  boxaReplaceBox(boxa, i, boxt);
1199  }
1200  return 0;
1201 }
1202 
1203 
1216 l_ok
1218 {
1219 l_int32 i, n;
1220 
1221  PROCNAME("boxaClear");
1222 
1223  if (!boxa)
1224  return ERROR_INT("boxa not defined", procName, 1);
1225 
1226  n = boxaGetCount(boxa);
1227  for (i = 0; i < n; i++)
1228  boxDestroy(&boxa->box[i]);
1229  boxa->n = 0;
1230  return 0;
1231 }
1232 
1233 
1234 /*--------------------------------------------------------------------------*
1235  * Boxaa creation, destruction *
1236  *--------------------------------------------------------------------------*/
1243 BOXAA *
1244 boxaaCreate(l_int32 n)
1245 {
1246 BOXAA *baa;
1247 
1248  PROCNAME("boxaaCreate");
1249 
1250  if (n <= 0 || n > MaxBoxaaPtrArraySize)
1251  n = InitialPtrArraySize;
1252 
1253  baa = (BOXAA *)LEPT_CALLOC(1, sizeof(BOXAA));
1254  if ((baa->boxa = (BOXA **)LEPT_CALLOC(n, sizeof(BOXA *))) == NULL) {
1255  boxaaDestroy(&baa);
1256  return (BOXAA *)ERROR_PTR("boxa ptr array not made", procName, NULL);
1257  }
1258  baa->nalloc = n;
1259  baa->n = 0;
1260  return baa;
1261 }
1262 
1263 
1278 BOXAA *
1280  l_int32 copyflag)
1281 {
1282 l_int32 i, n;
1283 BOXA *boxa;
1284 BOXAA *baad;
1285 
1286  PROCNAME("boxaaCopy");
1287 
1288  if (!baas)
1289  return (BOXAA *)ERROR_PTR("baas not defined", procName, NULL);
1290  if (copyflag != L_COPY && copyflag != L_CLONE)
1291  return (BOXAA *)ERROR_PTR("invalid copyflag", procName, NULL);
1292 
1293  n = boxaaGetCount(baas);
1294  baad = boxaaCreate(n);
1295  for (i = 0; i < n; i++) {
1296  boxa = boxaaGetBoxa(baas, i, copyflag);
1297  boxaaAddBoxa(baad, boxa, L_INSERT);
1298  }
1299 
1300  return baad;
1301 }
1302 
1303 
1309 void
1311 {
1312 l_int32 i;
1313 BOXAA *baa;
1314 
1315  PROCNAME("boxaaDestroy");
1316 
1317  if (pbaa == NULL) {
1318  L_WARNING("ptr address is NULL!\n", procName);
1319  return;
1320  }
1321 
1322  if ((baa = *pbaa) == NULL)
1323  return;
1324 
1325  for (i = 0; i < baa->n; i++)
1326  boxaDestroy(&baa->boxa[i]);
1327  LEPT_FREE(baa->boxa);
1328  LEPT_FREE(baa);
1329  *pbaa = NULL;
1330 }
1331 
1332 
1333 
1334 /*--------------------------------------------------------------------------*
1335  * Add Boxa to Boxaa *
1336  *--------------------------------------------------------------------------*/
1345 l_ok
1347  BOXA *ba,
1348  l_int32 copyflag)
1349 {
1350 l_int32 n;
1351 BOXA *bac;
1352 
1353  PROCNAME("boxaaAddBoxa");
1354 
1355  if (!baa)
1356  return ERROR_INT("baa not defined", procName, 1);
1357  if (!ba)
1358  return ERROR_INT("ba not defined", procName, 1);
1359  if (copyflag != L_INSERT && copyflag != L_COPY && copyflag != L_CLONE)
1360  return ERROR_INT("invalid copyflag", procName, 1);
1361 
1362  if (copyflag == L_INSERT)
1363  bac = ba;
1364  else
1365  bac = boxaCopy(ba, copyflag);
1366 
1367  n = boxaaGetCount(baa);
1368  if (n >= baa->nalloc) {
1369  if (boxaaExtendArray(baa))
1370  return ERROR_INT("extension failed", procName, 1);
1371  }
1372  baa->boxa[n] = bac;
1373  baa->n++;
1374  return 0;
1375 }
1376 
1377 
1390 l_ok
1392 {
1393  PROCNAME("boxaaExtendArray");
1394 
1395  if (!baa)
1396  return ERROR_INT("baa not defined", procName, 1);
1397 
1398  return boxaaExtendArrayToSize(baa, 2 * baa->nalloc);
1399 }
1400 
1401 
1415 l_ok
1417  l_int32 size)
1418 {
1419 size_t oldsize, newsize;
1420 
1421  PROCNAME("boxaaExtendArrayToSize");
1422 
1423  if (!baa)
1424  return ERROR_INT("baa not defined", procName, 1);
1425  if (baa->nalloc > MaxBoxaaPtrArraySize) /* belt & suspenders */
1426  return ERROR_INT("baa has too many ptrs", procName, 1);
1427  if (size > MaxBoxaaPtrArraySize)
1428  return ERROR_INT("size > 1M boxa ptrs; too large", procName, 1);
1429  if (size <= baa->nalloc) {
1430  L_INFO("size too small; no extension\n", procName);
1431  return 0;
1432  }
1433 
1434  oldsize = baa->nalloc * sizeof(BOXA *);
1435  newsize = size * sizeof(BOXA *);
1436  if ((baa->boxa = (BOXA **)reallocNew((void **)&baa->boxa,
1437  oldsize, newsize)) == NULL)
1438  return ERROR_INT("new ptr array not returned", procName, 1);
1439  baa->nalloc = size;
1440  return 0;
1441 }
1442 
1443 
1444 /*----------------------------------------------------------------------*
1445  * Boxaa accessors *
1446  *----------------------------------------------------------------------*/
1453 l_int32
1455 {
1456  PROCNAME("boxaaGetCount");
1457 
1458  if (!baa)
1459  return ERROR_INT("baa not defined", procName, 0);
1460  return baa->n;
1461 }
1462 
1463 
1470 l_int32
1472 {
1473 BOXA *boxa;
1474 l_int32 n, sum, i;
1475 
1476  PROCNAME("boxaaGetBoxCount");
1477 
1478  if (!baa)
1479  return ERROR_INT("baa not defined", procName, 0);
1480 
1481  n = boxaaGetCount(baa);
1482  for (sum = 0, i = 0; i < n; i++) {
1483  boxa = boxaaGetBoxa(baa, i, L_CLONE);
1484  sum += boxaGetCount(boxa);
1485  boxaDestroy(&boxa);
1486  }
1487 
1488  return sum;
1489 }
1490 
1491 
1500 BOXA *
1502  l_int32 index,
1503  l_int32 accessflag)
1504 {
1505 l_int32 n;
1506 
1507  PROCNAME("boxaaGetBoxa");
1508 
1509  if (!baa)
1510  return (BOXA *)ERROR_PTR("baa not defined", procName, NULL);
1511  n = boxaaGetCount(baa);
1512  if (index < 0 || index >= n)
1513  return (BOXA *)ERROR_PTR("index not valid", procName, NULL);
1514  if (accessflag != L_COPY && accessflag != L_CLONE)
1515  return (BOXA *)ERROR_PTR("invalid accessflag", procName, NULL);
1516 
1517  return boxaCopy(baa->boxa[index], accessflag);
1518 }
1519 
1520 
1530 BOX *
1532  l_int32 iboxa,
1533  l_int32 ibox,
1534  l_int32 accessflag)
1535 {
1536 BOX *box;
1537 BOXA *boxa;
1538 
1539  PROCNAME("boxaaGetBox");
1540 
1541  if ((boxa = boxaaGetBoxa(baa, iboxa, L_CLONE)) == NULL)
1542  return (BOX *)ERROR_PTR("boxa not retrieved", procName, NULL);
1543  if ((box = boxaGetBox(boxa, ibox, accessflag)) == NULL)
1544  L_ERROR("box not retrieved\n", procName);
1545  boxaDestroy(&boxa);
1546  return box;
1547 }
1548 
1549 
1550 /*----------------------------------------------------------------------*
1551  * Boxaa array modifiers *
1552  *----------------------------------------------------------------------*/
1582 l_ok
1584  BOXA *boxa)
1585 {
1586 l_int32 i, n;
1587 BOXA *boxat;
1588 
1589  PROCNAME("boxaaInitFull");
1590 
1591  if (!baa)
1592  return ERROR_INT("baa not defined", procName, 1);
1593  if (!boxa)
1594  return ERROR_INT("boxa not defined", procName, 1);
1595 
1596  n = baa->nalloc;
1597  baa->n = n;
1598  for (i = 0; i < n; i++) {
1599  boxat = boxaCopy(boxa, L_COPY);
1600  boxaaReplaceBoxa(baa, i, boxat);
1601  }
1602  return 0;
1603 }
1604 
1605 
1622 l_ok
1624  l_int32 maxindex,
1625  BOXA *boxa)
1626 {
1627 l_int32 i, n;
1628 
1629  PROCNAME("boxaaExtendWithInit");
1630 
1631  if (!baa)
1632  return ERROR_INT("baa not defined", procName, 1);
1633  if (!boxa)
1634  return ERROR_INT("boxa not defined", procName, 1);
1635 
1636  /* Extend the ptr array if necessary */
1637  n = boxaaGetCount(baa);
1638  if (maxindex < n) return 0;
1639  if (boxaaExtendArrayToSize(baa, maxindex + 1))
1640  return ERROR_INT("extension failed", procName, 1);
1641 
1642  /* Fill the new entries with copies of boxa */
1643  for (i = n; i <= maxindex; i++)
1644  boxaaAddBoxa(baa, boxa, L_COPY);
1645  return 0;
1646 }
1647 
1648 
1664 l_ok
1666  l_int32 index,
1667  BOXA *boxa)
1668 {
1669 l_int32 n;
1670 
1671  PROCNAME("boxaaReplaceBoxa");
1672 
1673  if (!baa)
1674  return ERROR_INT("baa not defined", procName, 1);
1675  if (!boxa)
1676  return ERROR_INT("boxa not defined", procName, 1);
1677  n = boxaaGetCount(baa);
1678  if (index < 0 || index >= n)
1679  return ERROR_INT("index not valid", procName, 1);
1680 
1681  boxaDestroy(&baa->boxa[index]);
1682  baa->boxa[index] = boxa;
1683  return 0;
1684 }
1685 
1686 
1706 l_ok
1708  l_int32 index,
1709  BOXA *boxa)
1710 {
1711 l_int32 i, n;
1712 BOXA **array;
1713 
1714  PROCNAME("boxaaInsertBoxa");
1715 
1716  if (!baa)
1717  return ERROR_INT("baa not defined", procName, 1);
1718  n = boxaaGetCount(baa);
1719  if (index < 0 || index > n) {
1720  L_ERROR("index %d not in [0,...,%d]\n", procName, index, n);
1721  return 1;
1722  }
1723  if (!boxa)
1724  return ERROR_INT("boxa not defined", procName, 1);
1725 
1726  if (n >= baa->nalloc) {
1727  if (boxaaExtendArray(baa))
1728  return ERROR_INT("extension failed", procName, 1);
1729  }
1730  array = baa->boxa;
1731  baa->n++;
1732  for (i = n; i > index; i--)
1733  array[i] = array[i - 1];
1734  array[index] = boxa;
1735  return 0;
1736 }
1737 
1738 
1755 l_ok
1757  l_int32 index)
1758 {
1759 l_int32 i, n;
1760 BOXA **array;
1761 
1762  PROCNAME("boxaaRemoveBox");
1763 
1764  if (!baa)
1765  return ERROR_INT("baa not defined", procName, 1);
1766  n = boxaaGetCount(baa);
1767  if (index < 0 || index >= n)
1768  return ERROR_INT("index not valid", procName, 1);
1769 
1770  array = baa->boxa;
1771  boxaDestroy(&array[index]);
1772  for (i = index + 1; i < n; i++)
1773  array[i - 1] = array[i];
1774  array[n - 1] = NULL;
1775  baa->n--;
1776 
1777  return 0;
1778 }
1779 
1780 
1795 l_ok
1797  l_int32 index,
1798  BOX *box,
1799  l_int32 accessflag)
1800 {
1801 l_int32 n;
1802 BOXA *boxa;
1803  PROCNAME("boxaaAddBox");
1804 
1805  if (!baa)
1806  return ERROR_INT("baa not defined", procName, 1);
1807  n = boxaaGetCount(baa);
1808  if (index < 0 || index >= n)
1809  return ERROR_INT("index not valid", procName, 1);
1810  if (accessflag != L_INSERT && accessflag != L_COPY && accessflag != L_CLONE)
1811  return ERROR_INT("invalid accessflag", procName, 1);
1812 
1813  boxa = boxaaGetBoxa(baa, index, L_CLONE);
1814  boxaAddBox(boxa, box, accessflag);
1815  boxaDestroy(&boxa);
1816  return 0;
1817 }
1818 
1819 
1820 /*---------------------------------------------------------------------*
1821  * Boxaa serialized I/O *
1822  *---------------------------------------------------------------------*/
1843 BOXAA *
1844 boxaaReadFromFiles(const char *dirname,
1845  const char *substr,
1846  l_int32 first,
1847  l_int32 nfiles)
1848 {
1849 char *fname;
1850 l_int32 i, n;
1851 BOXA *boxa;
1852 BOXAA *baa;
1853 SARRAY *sa;
1854 
1855  PROCNAME("boxaaReadFromFiles");
1856 
1857  if (!dirname)
1858  return (BOXAA *)ERROR_PTR("dirname not defined", procName, NULL);
1859 
1860  sa = getSortedPathnamesInDirectory(dirname, substr, first, nfiles);
1861  if (!sa || ((n = sarrayGetCount(sa)) == 0)) {
1862  sarrayDestroy(&sa);
1863  return (BOXAA *)ERROR_PTR("no pixa files found", procName, NULL);
1864  }
1865 
1866  baa = boxaaCreate(n);
1867  for (i = 0; i < n; i++) {
1868  fname = sarrayGetString(sa, i, L_NOCOPY);
1869  if ((boxa = boxaRead(fname)) == NULL) {
1870  L_ERROR("boxa not read for %d-th file", procName, i);
1871  continue;
1872  }
1873  boxaaAddBoxa(baa, boxa, L_INSERT);
1874  }
1875 
1876  sarrayDestroy(&sa);
1877  return baa;
1878 }
1879 
1880 
1887 BOXAA *
1888 boxaaRead(const char *filename)
1889 {
1890 FILE *fp;
1891 BOXAA *baa;
1892 
1893  PROCNAME("boxaaRead");
1894 
1895  if (!filename)
1896  return (BOXAA *)ERROR_PTR("filename not defined", procName, NULL);
1897 
1898  if ((fp = fopenReadStream(filename)) == NULL)
1899  return (BOXAA *)ERROR_PTR("stream not opened", procName, NULL);
1900  baa = boxaaReadStream(fp);
1901  fclose(fp);
1902  if (!baa)
1903  return (BOXAA *)ERROR_PTR("boxaa not read", procName, NULL);
1904  return baa;
1905 }
1906 
1907 
1919 BOXAA *
1921 {
1922 l_int32 n, i, x, y, w, h, version;
1923 l_int32 ignore;
1924 BOXA *boxa;
1925 BOXAA *baa;
1926 
1927  PROCNAME("boxaaReadStream");
1928 
1929  if (!fp)
1930  return (BOXAA *)ERROR_PTR("stream not defined", procName, NULL);
1931 
1932  if (fscanf(fp, "\nBoxaa Version %d\n", &version) != 1)
1933  return (BOXAA *)ERROR_PTR("not a boxaa file", procName, NULL);
1934  if (version != BOXAA_VERSION_NUMBER)
1935  return (BOXAA *)ERROR_PTR("invalid boxa version", procName, NULL);
1936  if (fscanf(fp, "Number of boxa = %d\n", &n) != 1)
1937  return (BOXAA *)ERROR_PTR("not a boxaa file", procName, NULL);
1938  if (n < 0)
1939  return (BOXAA *)ERROR_PTR("num boxa ptrs < 0", procName, NULL);
1940  if (n > MaxBoxaaPtrArraySize)
1941  return (BOXAA *)ERROR_PTR("too many boxa ptrs", procName, NULL);
1942  if (n == 0) L_INFO("the boxaa is empty\n", procName);
1943 
1944  if ((baa = boxaaCreate(n)) == NULL)
1945  return (BOXAA *)ERROR_PTR("boxaa not made", procName, NULL);
1946  for (i = 0; i < n; i++) {
1947  if (fscanf(fp, "\nBoxa[%d] extent: x = %d, y = %d, w = %d, h = %d",
1948  &ignore, &x, &y, &w, &h) != 5) {
1949  boxaaDestroy(&baa);
1950  return (BOXAA *)ERROR_PTR("boxa descr not valid", procName, NULL);
1951  }
1952  if ((boxa = boxaReadStream(fp)) == NULL) {
1953  boxaaDestroy(&baa);
1954  return (BOXAA *)ERROR_PTR("boxa not made", procName, NULL);
1955  }
1956  boxaaAddBoxa(baa, boxa, L_INSERT);
1957  }
1958  return baa;
1959 }
1960 
1961 
1969 BOXAA *
1970 boxaaReadMem(const l_uint8 *data,
1971  size_t size)
1972 {
1973 FILE *fp;
1974 BOXAA *baa;
1975 
1976  PROCNAME("boxaaReadMem");
1977 
1978  if (!data)
1979  return (BOXAA *)ERROR_PTR("data not defined", procName, NULL);
1980  if ((fp = fopenReadFromMemory(data, size)) == NULL)
1981  return (BOXAA *)ERROR_PTR("stream not opened", procName, NULL);
1982 
1983  baa = boxaaReadStream(fp);
1984  fclose(fp);
1985  if (!baa) L_ERROR("baa not read\n", procName);
1986  return baa;
1987 }
1988 
1989 
1997 l_ok
1998 boxaaWrite(const char *filename,
1999  BOXAA *baa)
2000 {
2001 l_int32 ret;
2002 FILE *fp;
2003 
2004  PROCNAME("boxaaWrite");
2005 
2006  if (!filename)
2007  return ERROR_INT("filename not defined", procName, 1);
2008  if (!baa)
2009  return ERROR_INT("baa not defined", procName, 1);
2010 
2011  if ((fp = fopenWriteStream(filename, "w")) == NULL)
2012  return ERROR_INT("stream not opened", procName, 1);
2013  ret = boxaaWriteStream(fp, baa);
2014  fclose(fp);
2015  if (ret)
2016  return ERROR_INT("baa not written to stream", procName, 1);
2017  return 0;
2018 }
2019 
2020 
2028 l_ok
2030  BOXAA *baa)
2031 {
2032 l_int32 n, i, x, y, w, h;
2033 BOX *box;
2034 BOXA *boxa;
2035 
2036  PROCNAME("boxaaWriteStream");
2037 
2038  if (!fp)
2039  return ERROR_INT("stream not defined", procName, 1);
2040  if (!baa)
2041  return ERROR_INT("baa not defined", procName, 1);
2042 
2043  n = boxaaGetCount(baa);
2044  fprintf(fp, "\nBoxaa Version %d\n", BOXAA_VERSION_NUMBER);
2045  fprintf(fp, "Number of boxa = %d\n", n);
2046 
2047  for (i = 0; i < n; i++) {
2048  if ((boxa = boxaaGetBoxa(baa, i, L_CLONE)) == NULL)
2049  return ERROR_INT("boxa not found", procName, 1);
2050  boxaGetExtent(boxa, NULL, NULL, &box);
2051  boxGetGeometry(box, &x, &y, &w, &h);
2052  fprintf(fp, "\nBoxa[%d] extent: x = %d, y = %d, w = %d, h = %d",
2053  i, x, y, w, h);
2054  boxaWriteStream(fp, boxa);
2055  boxDestroy(&box);
2056  boxaDestroy(&boxa);
2057  }
2058  return 0;
2059 }
2060 
2061 
2075 l_ok
2076 boxaaWriteMem(l_uint8 **pdata,
2077  size_t *psize,
2078  BOXAA *baa)
2079 {
2080 l_int32 ret;
2081 FILE *fp;
2082 
2083  PROCNAME("boxaaWriteMem");
2084 
2085  if (pdata) *pdata = NULL;
2086  if (psize) *psize = 0;
2087  if (!pdata)
2088  return ERROR_INT("&data not defined", procName, 1);
2089  if (!psize)
2090  return ERROR_INT("&size not defined", procName, 1);
2091  if (!baa)
2092  return ERROR_INT("baa not defined", procName, 1);
2093 
2094 #if HAVE_FMEMOPEN
2095  if ((fp = open_memstream((char **)pdata, psize)) == NULL)
2096  return ERROR_INT("stream not opened", procName, 1);
2097  ret = boxaaWriteStream(fp, baa);
2098  fputc('\0', fp);
2099  fclose(fp);
2100  *psize = *psize - 1;
2101 #else
2102  L_INFO("work-around: writing to a temp file\n", procName);
2103  #ifdef _WIN32
2104  if ((fp = fopenWriteWinTempfile()) == NULL)
2105  return ERROR_INT("tmpfile stream not opened", procName, 1);
2106  #else
2107  if ((fp = tmpfile()) == NULL)
2108  return ERROR_INT("tmpfile stream not opened", procName, 1);
2109  #endif /* _WIN32 */
2110  ret = boxaaWriteStream(fp, baa);
2111  rewind(fp);
2112  *pdata = l_binaryReadStream(fp, psize);
2113  fclose(fp);
2114 #endif /* HAVE_FMEMOPEN */
2115  return ret;
2116 }
2117 
2118 
2119 /*---------------------------------------------------------------------*
2120  * Boxa serialized I/O *
2121  *---------------------------------------------------------------------*/
2128 BOXA *
2129 boxaRead(const char *filename)
2130 {
2131 FILE *fp;
2132 BOXA *boxa;
2133 
2134  PROCNAME("boxaRead");
2135 
2136  if (!filename)
2137  return (BOXA *)ERROR_PTR("filename not defined", procName, NULL);
2138 
2139  if ((fp = fopenReadStream(filename)) == NULL)
2140  return (BOXA *)ERROR_PTR("stream not opened", procName, NULL);
2141  boxa = boxaReadStream(fp);
2142  fclose(fp);
2143  if (!boxa)
2144  return (BOXA *)ERROR_PTR("boxa not read", procName, NULL);
2145  return boxa;
2146 }
2147 
2148 
2160 BOXA *
2162 {
2163 l_int32 n, i, x, y, w, h, version;
2164 l_int32 ignore;
2165 BOX *box;
2166 BOXA *boxa;
2167 
2168  PROCNAME("boxaReadStream");
2169 
2170  if (!fp)
2171  return (BOXA *)ERROR_PTR("stream not defined", procName, NULL);
2172 
2173  if (fscanf(fp, "\nBoxa Version %d\n", &version) != 1)
2174  return (BOXA *)ERROR_PTR("not a boxa file", procName, NULL);
2175  if (version != BOXA_VERSION_NUMBER)
2176  return (BOXA *)ERROR_PTR("invalid boxa version", procName, NULL);
2177  if (fscanf(fp, "Number of boxes = %d\n", &n) != 1)
2178  return (BOXA *)ERROR_PTR("not a boxa file", procName, NULL);
2179  if (n < 0)
2180  return (BOXA *)ERROR_PTR("num box ptrs < 0", procName, NULL);
2181  if (n > MaxBoxaPtrArraySize)
2182  return (BOXA *)ERROR_PTR("too many box ptrs", procName, NULL);
2183  if (n == 0) L_INFO("the boxa is empty\n", procName);
2184 
2185  if ((boxa = boxaCreate(n)) == NULL)
2186  return (BOXA *)ERROR_PTR("boxa not made", procName, NULL);
2187  for (i = 0; i < n; i++) {
2188  if (fscanf(fp, " Box[%d]: x = %d, y = %d, w = %d, h = %d\n",
2189  &ignore, &x, &y, &w, &h) != 5) {
2190  boxaDestroy(&boxa);
2191  return (BOXA *)ERROR_PTR("box descr not valid", procName, NULL);
2192  }
2193  box = boxCreate(x, y, w, h);
2194  boxaAddBox(boxa, box, L_INSERT);
2195  }
2196  return boxa;
2197 }
2198 
2199 
2207 BOXA *
2208 boxaReadMem(const l_uint8 *data,
2209  size_t size)
2210 {
2211 FILE *fp;
2212 BOXA *boxa;
2213 
2214  PROCNAME("boxaReadMem");
2215 
2216  if (!data)
2217  return (BOXA *)ERROR_PTR("data not defined", procName, NULL);
2218  if ((fp = fopenReadFromMemory(data, size)) == NULL)
2219  return (BOXA *)ERROR_PTR("stream not opened", procName, NULL);
2220 
2221  boxa = boxaReadStream(fp);
2222  fclose(fp);
2223  if (!boxa) L_ERROR("boxa not read\n", procName);
2224  return boxa;
2225 }
2226 
2227 
2244 l_ok
2245 boxaWriteDebug(const char *filename,
2246  BOXA *boxa)
2247 {
2248  PROCNAME("boxaWriteDebug");
2249 
2250  if (LeptDebugOK) {
2251  return boxaWrite(filename, boxa);
2252  } else {
2253  L_INFO("write to named temp file %s is disabled\n", procName, filename);
2254  return 0;
2255  }
2256 }
2257 
2258 
2266 l_ok
2267 boxaWrite(const char *filename,
2268  BOXA *boxa)
2269 {
2270 l_int32 ret;
2271 FILE *fp;
2272 
2273  PROCNAME("boxaWrite");
2274 
2275  if (!filename)
2276  return ERROR_INT("filename not defined", procName, 1);
2277  if (!boxa)
2278  return ERROR_INT("boxa not defined", procName, 1);
2279 
2280  if ((fp = fopenWriteStream(filename, "w")) == NULL)
2281  return ERROR_INT("stream not opened", procName, 1);
2282  ret = boxaWriteStream(fp, boxa);
2283  fclose(fp);
2284  if (ret)
2285  return ERROR_INT("boxa not written to stream", procName, 1);
2286 
2287  return 0;
2288 }
2289 
2290 
2298 l_ok
2300  BOXA *boxa)
2301 {
2302 l_int32 n, i;
2303 BOX *box;
2304 
2305  PROCNAME("boxaWriteStream");
2306 
2307  if (!boxa)
2308  return ERROR_INT("boxa not defined", procName, 1);
2309  if (!fp)
2310  return boxaWriteStderr(boxa);
2311 
2312  n = boxaGetCount(boxa);
2313  fprintf(fp, "\nBoxa Version %d\n", BOXA_VERSION_NUMBER);
2314  fprintf(fp, "Number of boxes = %d\n", n);
2315  for (i = 0; i < n; i++) {
2316  if ((box = boxaGetBox(boxa, i, L_CLONE)) == NULL)
2317  return ERROR_INT("box not found", procName, 1);
2318  fprintf(fp, " Box[%d]: x = %d, y = %d, w = %d, h = %d\n",
2319  i, box->x, box->y, box->w, box->h);
2320  boxDestroy(&box);
2321  }
2322  return 0;
2323 }
2324 
2325 
2332 l_ok
2334 {
2335 l_int32 n, i;
2336 BOX *box;
2337 
2338  PROCNAME("boxaWriteStderr");
2339 
2340  if (!boxa)
2341  return ERROR_INT("boxa not defined", procName, 1);
2342 
2343  n = boxaGetCount(boxa);
2344  lept_stderr("\nBoxa Version %d\n", BOXA_VERSION_NUMBER);
2345  lept_stderr("Number of boxes = %d\n", n);
2346  for (i = 0; i < n; i++) {
2347  if ((box = boxaGetBox(boxa, i, L_CLONE)) == NULL)
2348  return ERROR_INT("box not found", procName, 1);
2349  lept_stderr(" Box[%d]: x = %d, y = %d, w = %d, h = %d\n",
2350  i, box->x, box->y, box->w, box->h);
2351  boxDestroy(&box);
2352  }
2353  return 0;
2354 }
2355 
2356 
2370 l_ok
2371 boxaWriteMem(l_uint8 **pdata,
2372  size_t *psize,
2373  BOXA *boxa)
2374 {
2375 l_int32 ret;
2376 FILE *fp;
2377 
2378  PROCNAME("boxaWriteMem");
2379 
2380  if (pdata) *pdata = NULL;
2381  if (psize) *psize = 0;
2382  if (!pdata)
2383  return ERROR_INT("&data not defined", procName, 1);
2384  if (!psize)
2385  return ERROR_INT("&size not defined", procName, 1);
2386  if (!boxa)
2387  return ERROR_INT("boxa not defined", procName, 1);
2388 
2389 #if HAVE_FMEMOPEN
2390  if ((fp = open_memstream((char **)pdata, psize)) == NULL)
2391  return ERROR_INT("stream not opened", procName, 1);
2392  ret = boxaWriteStream(fp, boxa);
2393  fputc('\0', fp);
2394  fclose(fp);
2395  *psize = *psize - 1;
2396 #else
2397  L_INFO("work-around: writing to a temp file\n", procName);
2398  #ifdef _WIN32
2399  if ((fp = fopenWriteWinTempfile()) == NULL)
2400  return ERROR_INT("tmpfile stream not opened", procName, 1);
2401  #else
2402  if ((fp = tmpfile()) == NULL)
2403  return ERROR_INT("tmpfile stream not opened", procName, 1);
2404  #endif /* _WIN32 */
2405  ret = boxaWriteStream(fp, boxa);
2406  rewind(fp);
2407  *pdata = l_binaryReadStream(fp, psize);
2408  fclose(fp);
2409 #endif /* HAVE_FMEMOPEN */
2410  return ret;
2411 }
2412 
2413 
2414 /*---------------------------------------------------------------------*
2415  * Debug printing *
2416  *---------------------------------------------------------------------*/
2430 l_ok
2432  BOX *box)
2433 {
2434  PROCNAME("boxPrintStreamInfo");
2435 
2436  if (!box)
2437  return ERROR_INT("box not defined", procName, 1);
2438 
2439  if (!fp) { /* output to stderr */
2440  lept_stderr(" Box: x = %d, y = %d, w = %d, h = %d\n",
2441  box->x, box->y, box->w, box->h);
2442  } else {
2443  fprintf(fp, " Box: x = %d, y = %d, w = %d, h = %d\n",
2444  box->x, box->y, box->w, box->h);
2445  }
2446  return 0;
2447 }
l_ok boxaaWrite(const char *filename, BOXAA *baa)
boxaaWrite()
Definition: boxbasic.c:1998
#define BOXAA_VERSION_NUMBER
Definition: pix.h:452
BOXA * boxaReadStream(FILE *fp)
boxaReadStream()
Definition: boxbasic.c:2161
BOXAA * boxaaReadStream(FILE *fp)
boxaaReadStream()
Definition: boxbasic.c:1920
BOX * boxaGetValidBox(BOXA *boxa, l_int32 index, l_int32 accessflag)
boxaGetValidBox()
Definition: boxbasic.c:818
l_int32 n
Definition: pix.h:493
l_uint32 refcount
Definition: pix.h:495
l_ok boxaaReplaceBoxa(BOXAA *baa, l_int32 index, BOXA *boxa)
boxaaReplaceBoxa()
Definition: boxbasic.c:1665
Definition: pix.h:713
l_ok boxSetSideLocations(BOX *box, l_int32 l, l_int32 r, l_int32 t, l_int32 b)
boxSetSideLocations()
Definition: boxbasic.c:408
l_int32 boxaaGetCount(BOXAA *baa)
boxaaGetCount()
Definition: boxbasic.c:1454
l_uint32 refcount
Definition: pix.h:486
l_ok boxaExtendArray(BOXA *boxa)
boxaExtendArray()
Definition: boxbasic.c:671
BOXAA * boxaaReadMem(const l_uint8 *data, size_t size)
boxaaReadMem()
Definition: boxbasic.c:1970
Definition: pix.h:712
l_ok boxGetSideLocations(BOX *box, l_int32 *pl, l_int32 *pr, l_int32 *pt, l_int32 *pb)
boxGetSideLocations()
Definition: boxbasic.c:374
l_ok boxaWriteStream(FILE *fp, BOXA *boxa)
boxaWriteStream()
Definition: boxbasic.c:2299
l_int32 y
Definition: pix.h:483
NUMA * numaMakeConstant(l_float32 val, l_int32 size)
numaMakeConstant()
Definition: numafunc1.c:851
void lept_stderr(const char *fmt,...)
lept_stderr()
Definition: utils1.c:306
Definition: pix.h:710
struct Boxa ** boxa
Definition: pix.h:505
l_ok boxaReplaceBox(BOXA *boxa, l_int32 index, BOX *box)
boxaReplaceBox()
Definition: boxbasic.c:962
l_ok boxaaExtendWithInit(BOXAA *baa, l_int32 maxindex, BOXA *boxa)
boxaaExtendWithInit()
Definition: boxbasic.c:1623
FILE * fopenReadFromMemory(const l_uint8 *data, size_t size)
fopenReadFromMemory()
Definition: utils2.c:2009
BOXA * boxaCopy(BOXA *boxa, l_int32 copyflag)
boxaCopy()
Definition: boxbasic.c:537
void boxaDestroy(BOXA **pboxa)
boxaDestroy()
Definition: boxbasic.c:583
Definition: pix.h:491
l_ok numaSetValue(NUMA *na, l_int32 index, l_float32 val)
numaSetValue()
Definition: numabasic.c:786
Definition: array.h:126
Definition: pix.h:501
BOX * boxClone(BOX *box)
boxClone()
Definition: boxbasic.c:256
l_ok boxaaWriteStream(FILE *fp, BOXAA *baa)
boxaaWriteStream()
Definition: boxbasic.c:2029
l_int32 nalloc
Definition: pix.h:504
l_ok boxaaAddBoxa(BOXAA *baa, BOXA *ba, l_int32 copyflag)
boxaaAddBoxa()
Definition: boxbasic.c:1346
BOXAA * boxaaReadFromFiles(const char *dirname, const char *substr, l_int32 first, l_int32 nfiles)
boxaaReadFromFiles()
Definition: boxbasic.c:1844
l_ok boxaaRemoveBoxa(BOXAA *baa, l_int32 index)
boxaaRemoveBoxa()
Definition: boxbasic.c:1756
Definition: array.h:70
void boxaaDestroy(BOXAA **pbaa)
boxaaDestroy()
Definition: boxbasic.c:1310
l_ok boxaRemoveBoxAndSave(BOXA *boxa, l_int32 index, BOX **pbox)
boxaRemoveBoxAndSave()
Definition: boxbasic.c:1072
BOX * boxCreateValid(l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxCreateValid()
Definition: boxbasic.c:215
l_int32 nalloc
Definition: pix.h:494
l_int32 w
Definition: pix.h:484
BOXA * boxaReadMem(const l_uint8 *data, size_t size)
boxaReadMem()
Definition: boxbasic.c:2208
l_ok boxaGetBoxGeometry(BOXA *boxa, l_int32 index, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxaGetBoxGeometry()
Definition: boxbasic.c:879
BOXA * boxaSaveValid(BOXA *boxas, l_int32 copyflag)
boxaSaveValid()
Definition: boxbasic.c:1116
l_ok boxaAddBox(BOXA *boxa, BOX *box, l_int32 copyflag)
boxaAddBox()
Definition: boxbasic.c:620
l_ok boxaWriteDebug(const char *filename, BOXA *boxa)
boxaWriteDebug()
Definition: boxbasic.c:2245
l_ok boxaExtendArrayToSize(BOXA *boxa, size_t size)
boxaExtendArrayToSize()
Definition: boxbasic.c:696
l_ok boxaaAddBox(BOXAA *baa, l_int32 index, BOX *box, l_int32 accessflag)
boxaaAddBox()
Definition: boxbasic.c:1796
char * sarrayGetString(SARRAY *sa, l_int32 index, l_int32 copyflag)
sarrayGetString()
Definition: sarray1.c:703
l_ok boxaWrite(const char *filename, BOXA *boxa)
boxaWrite()
Definition: boxbasic.c:2267
NUMA * boxaFindInvalidBoxes(BOXA *boxa)
boxaFindInvalidBoxes()
Definition: boxbasic.c:846
void * reallocNew(void **pindata, size_t oldsize, size_t newsize)
reallocNew()
Definition: utils2.c:1302
static const size_t InitialPtrArraySize
Definition: boxbasic.c:144
BOX * boxaGetBox(BOXA *boxa, l_int32 index, l_int32 accessflag)
boxaGetBox()
Definition: boxbasic.c:779
Definition: pix.h:711
SARRAY * getSortedPathnamesInDirectory(const char *dirname, const char *substr, l_int32 first, l_int32 nfiles)
getSortedPathnamesInDirectory()
Definition: sarray1.c:1848
l_int32 x
Definition: pix.h:482
l_ok boxaWriteMem(l_uint8 **pdata, size_t *psize, BOXA *boxa)
boxaWriteMem()
Definition: boxbasic.c:2371
l_ok boxaGetExtent(BOXA *boxa, l_int32 *pw, l_int32 *ph, BOX **pbox)
boxaGetExtent()
Definition: boxfunc4.c:953
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1975
FILE * fopenWriteWinTempfile(void)
fopenWriteWinTempfile()
Definition: utils2.c:2055
BOXAA * boxaaCreate(l_int32 n)
boxaaCreate()
Definition: boxbasic.c:1244
FILE * fopenReadStream(const char *filename)
fopenReadStream()
Definition: utils2.c:1932
l_ok boxaInitFull(BOXA *boxa, BOX *box)
boxaInitFull()
Definition: boxbasic.c:1180
l_int32 boxGetRefcount(BOX *box)
Return the current reference count of box.
Definition: boxbasic.c:436
l_uint8 * l_binaryReadStream(FILE *fp, size_t *pnbytes)
l_binaryReadStream()
Definition: utils2.c:1402
l_int32 sarrayGetCount(SARRAY *sa)
sarrayGetCount()
Definition: sarray1.c:643
BOXAA * boxaaRead(const char *filename)
boxaaRead()
Definition: boxbasic.c:1888
l_int32 n
Definition: pix.h:503
l_int32 boxaGetValidCount(BOXA *boxa)
boxaGetValidCount()
Definition: boxbasic.c:751
l_ok boxaIsFull(BOXA *boxa, l_int32 *pfull)
boxaIsFull()
Definition: boxbasic.c:915
l_ok boxaRemoveBox(BOXA *boxa, l_int32 index)
boxaRemoveBox()
Definition: boxbasic.c:1048
l_ok boxaWriteStderr(BOXA *boxa)
boxaWriteStderr()
Definition: boxbasic.c:2333
l_ok boxaaInitFull(BOXAA *baa, BOXA *boxa)
boxaaInitFull()
Definition: boxbasic.c:1583
l_int32 h
Definition: pix.h:485
#define BOXA_VERSION_NUMBER
Definition: pix.h:451
BOX * boxCopy(BOX *box)
boxCopy()
Definition: boxbasic.c:235
l_int32 boxaaGetBoxCount(BOXAA *baa)
boxaaGetBoxCount()
Definition: boxbasic.c:1471
BOX * boxaaGetBox(BOXAA *baa, l_int32 iboxa, l_int32 ibox, l_int32 accessflag)
boxaaGetBox()
Definition: boxbasic.c:1531
BOXA * boxaCreate(l_int32 n)
boxaCreate()
Definition: boxbasic.c:502
l_ok boxaaWriteMem(l_uint8 **pdata, size_t *psize, BOXAA *baa)
boxaaWriteMem()
Definition: boxbasic.c:2076
l_ok boxaaInsertBoxa(BOXAA *baa, l_int32 index, BOXA *boxa)
boxaaInsertBoxa()
Definition: boxbasic.c:1707
void boxDestroy(BOX **pbox)
boxDestroy()
Definition: boxbasic.c:282
l_int32 boxaGetCount(BOXA *boxa)
boxaGetCount()
Definition: boxbasic.c:734
l_ok boxPrintStreamInfo(FILE *fp, BOX *box)
boxPrintStreamInfo()
Definition: boxbasic.c:2431
l_ok boxaaExtendArray(BOXAA *baa)
boxaaExtendArray()
Definition: boxbasic.c:1391
l_ok boxSetGeometry(BOX *box, l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxSetGeometry()
Definition: boxbasic.c:343
l_ok boxaClear(BOXA *boxa)
boxaClear()
Definition: boxbasic.c:1217
struct Box ** box
Definition: pix.h:496
BOXAA * boxaaCopy(BOXAA *baas, l_int32 copyflag)
boxaaCopy()
Definition: boxbasic.c:1279
l_ok boxIsValid(BOX *box, l_int32 *pvalid)
boxIsValid()
Definition: boxbasic.c:475
l_ok boxGetGeometry(BOX *box, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxGetGeometry()
Definition: boxbasic.c:313
Definition: pix.h:480
BOX * boxCreate(l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxCreate()
Definition: boxbasic.c:172
BOXA * boxaRead(const char *filename)
boxaRead()
Definition: boxbasic.c:2129
l_ok boxChangeRefcount(BOX *box, l_int32 delta)
Adjust the current references count of box by delta.
Definition: boxbasic.c:454
l_ok boxaaExtendArrayToSize(BOXAA *baa, l_int32 size)
boxaaExtendArrayToSize()
Definition: boxbasic.c:1416
l_ok boxaInsertBox(BOXA *boxa, l_int32 index, BOX *box)
boxaInsertBox()
Definition: boxbasic.c:1000
BOXA * boxaaGetBoxa(BOXAA *baa, l_int32 index, l_int32 accessflag)
boxaaGetBoxa()
Definition: boxbasic.c:1501
void sarrayDestroy(SARRAY **psa)
sarrayDestroy()
Definition: sarray1.c:362