Leptonica  1.77.0
Image processing and image analysis suite
numabasic.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 
166 #include <string.h>
167 #include <math.h>
168 #include "allheaders.h"
169 
170 static const l_int32 INITIAL_PTR_ARRAYSIZE = 50; /* n'importe quoi */
171 
172  /* Static functions */
173 static l_int32 numaExtendArray(NUMA *na);
174 static l_int32 numaaExtendArray(NUMAA *naa);
175 
176 
177 /*--------------------------------------------------------------------------*
178  * Numa creation, destruction, copy, clone, etc. *
179  *--------------------------------------------------------------------------*/
186 NUMA *
187 numaCreate(l_int32 n)
188 {
189 NUMA *na;
190 
191  PROCNAME("numaCreate");
192 
193  if (n <= 0)
194  n = INITIAL_PTR_ARRAYSIZE;
195 
196  if ((na = (NUMA *)LEPT_CALLOC(1, sizeof(NUMA))) == NULL)
197  return (NUMA *)ERROR_PTR("na not made", procName, NULL);
198  if ((na->array = (l_float32 *)LEPT_CALLOC(n, sizeof(l_float32))) == NULL) {
199  numaDestroy(&na);
200  return (NUMA *)ERROR_PTR("number array not made", procName, NULL);
201  }
202 
203  na->nalloc = n;
204  na->n = 0;
205  na->refcount = 1;
206  na->startx = 0.0;
207  na->delx = 1.0;
208  return na;
209 }
210 
211 
227 NUMA *
228 numaCreateFromIArray(l_int32 *iarray,
229  l_int32 size)
230 {
231 l_int32 i;
232 NUMA *na;
233 
234  PROCNAME("numaCreateFromIArray");
235 
236  if (!iarray)
237  return (NUMA *)ERROR_PTR("iarray not defined", procName, NULL);
238  if (size <= 0)
239  return (NUMA *)ERROR_PTR("size must be > 0", procName, NULL);
240 
241  na = numaCreate(size);
242  for (i = 0; i < size; i++)
243  numaAddNumber(na, iarray[i]);
244 
245  return na;
246 }
247 
248 
264 NUMA *
265 numaCreateFromFArray(l_float32 *farray,
266  l_int32 size,
267  l_int32 copyflag)
268 {
269 l_int32 i;
270 NUMA *na;
271 
272  PROCNAME("numaCreateFromFArray");
273 
274  if (!farray)
275  return (NUMA *)ERROR_PTR("farray not defined", procName, NULL);
276  if (size <= 0)
277  return (NUMA *)ERROR_PTR("size must be > 0", procName, NULL);
278  if (copyflag != L_INSERT && copyflag != L_COPY)
279  return (NUMA *)ERROR_PTR("invalid copyflag", procName, NULL);
280 
281  na = numaCreate(size);
282  if (copyflag == L_INSERT) {
283  if (na->array) LEPT_FREE(na->array);
284  na->array = farray;
285  na->n = size;
286  } else { /* just copy the contents */
287  for (i = 0; i < size; i++)
288  numaAddNumber(na, farray[i]);
289  }
290 
291  return na;
292 }
293 
294 
308 NUMA *
309 numaCreateFromString(const char *str)
310 {
311 char *substr;
312 l_int32 i, n, nerrors;
313 l_float32 val;
314 NUMA *na;
315 SARRAY *sa;
316 
317  PROCNAME("numaCreateFromString");
318 
319  if (!str || (strlen(str) == 0))
320  return (NUMA *)ERROR_PTR("str not defined or empty", procName, NULL);
321 
322  sa = sarrayCreate(0);
323  sarraySplitString(sa, str, ",");
324  n = sarrayGetCount(sa);
325  na = numaCreate(n);
326  nerrors = 0;
327  for (i = 0; i < n; i++) {
328  substr = sarrayGetString(sa, i, L_NOCOPY);
329  if (sscanf(substr, "%f", &val) != 1) {
330  L_ERROR("substr %d not float\n", procName, i);
331  nerrors++;
332  } else {
333  numaAddNumber(na, val);
334  }
335  }
336 
337  sarrayDestroy(&sa);
338  if (nerrors > 0) {
339  numaDestroy(&na);
340  return (NUMA *)ERROR_PTR("non-floats in string", procName, NULL);
341  }
342 
343  return na;
344 }
345 
346 
359 void
361 {
362 NUMA *na;
363 
364  PROCNAME("numaDestroy");
365 
366  if (pna == NULL) {
367  L_WARNING("ptr address is NULL\n", procName);
368  return;
369  }
370 
371  if ((na = *pna) == NULL)
372  return;
373 
374  /* Decrement the ref count. If it is 0, destroy the numa. */
375  numaChangeRefcount(na, -1);
376  if (numaGetRefcount(na) <= 0) {
377  if (na->array)
378  LEPT_FREE(na->array);
379  LEPT_FREE(na);
380  }
381 
382  *pna = NULL;
383  return;
384 }
385 
386 
393 NUMA *
395 {
396 l_int32 i;
397 NUMA *cna;
398 
399  PROCNAME("numaCopy");
400 
401  if (!na)
402  return (NUMA *)ERROR_PTR("na not defined", procName, NULL);
403 
404  if ((cna = numaCreate(na->nalloc)) == NULL)
405  return (NUMA *)ERROR_PTR("cna not made", procName, NULL);
406  cna->startx = na->startx;
407  cna->delx = na->delx;
408 
409  for (i = 0; i < na->n; i++)
410  numaAddNumber(cna, na->array[i]);
411 
412  return cna;
413 }
414 
415 
422 NUMA *
424 {
425  PROCNAME("numaClone");
426 
427  if (!na)
428  return (NUMA *)ERROR_PTR("na not defined", procName, NULL);
429 
430  numaChangeRefcount(na, 1);
431  return na;
432 }
433 
434 
448 l_ok
450 {
451  PROCNAME("numaEmpty");
452 
453  if (!na)
454  return ERROR_INT("na not defined", procName, 1);
455 
456  na->n = 0;
457  return 0;
458 }
459 
460 
461 
462 /*--------------------------------------------------------------------------*
463  * Number array: add number and extend array *
464  *--------------------------------------------------------------------------*/
472 l_ok
474  l_float32 val)
475 {
476 l_int32 n;
477 
478  PROCNAME("numaAddNumber");
479 
480  if (!na)
481  return ERROR_INT("na not defined", procName, 1);
482 
483  n = numaGetCount(na);
484  if (n >= na->nalloc)
485  numaExtendArray(na);
486  na->array[n] = val;
487  na->n++;
488  return 0;
489 }
490 
491 
498 static l_int32
500 {
501  PROCNAME("numaExtendArray");
502 
503  if (!na)
504  return ERROR_INT("na not defined", procName, 1);
505 
506  if ((na->array = (l_float32 *)reallocNew((void **)&na->array,
507  sizeof(l_float32) * na->nalloc,
508  2 * sizeof(l_float32) * na->nalloc)) == NULL)
509  return ERROR_INT("new ptr array not returned", procName, 1);
510 
511  na->nalloc *= 2;
512  return 0;
513 }
514 
515 
533 l_ok
535  l_int32 index,
536  l_float32 val)
537 {
538 l_int32 i, n;
539 
540  PROCNAME("numaInsertNumber");
541 
542  if (!na)
543  return ERROR_INT("na not defined", procName, 1);
544  n = numaGetCount(na);
545  if (index < 0 || index > n)
546  return ERROR_INT("index not in {0...n}", procName, 1);
547 
548  if (n >= na->nalloc)
549  numaExtendArray(na);
550  for (i = n; i > index; i--)
551  na->array[i] = na->array[i - 1];
552  na->array[index] = val;
553  na->n++;
554  return 0;
555 }
556 
557 
572 l_ok
574  l_int32 index)
575 {
576 l_int32 i, n;
577 
578  PROCNAME("numaRemoveNumber");
579 
580  if (!na)
581  return ERROR_INT("na not defined", procName, 1);
582  n = numaGetCount(na);
583  if (index < 0 || index >= n)
584  return ERROR_INT("index not in {0...n - 1}", procName, 1);
585 
586  for (i = index + 1; i < n; i++)
587  na->array[i - 1] = na->array[i];
588  na->n--;
589  return 0;
590 }
591 
592 
601 l_ok
603  l_int32 index,
604  l_float32 val)
605 {
606 l_int32 n;
607 
608  PROCNAME("numaReplaceNumber");
609 
610  if (!na)
611  return ERROR_INT("na not defined", procName, 1);
612  n = numaGetCount(na);
613  if (index < 0 || index >= n)
614  return ERROR_INT("index not in {0...n - 1}", procName, 1);
615 
616  na->array[index] = val;
617  return 0;
618 }
619 
620 
621 /*----------------------------------------------------------------------*
622  * Numa accessors *
623  *----------------------------------------------------------------------*/
630 l_int32
632 {
633  PROCNAME("numaGetCount");
634 
635  if (!na)
636  return ERROR_INT("na not defined", procName, 0);
637  return na->n;
638 }
639 
640 
657 l_ok
659  l_int32 newcount)
660 {
661  PROCNAME("numaSetCount");
662 
663  if (!na)
664  return ERROR_INT("na not defined", procName, 1);
665  if (newcount > na->nalloc) {
666  if ((na->array = (l_float32 *)reallocNew((void **)&na->array,
667  sizeof(l_float32) * na->nalloc,
668  sizeof(l_float32) * newcount)) == NULL)
669  return ERROR_INT("new ptr array not returned", procName, 1);
670  na->nalloc = newcount;
671  }
672  na->n = newcount;
673  return 0;
674 }
675 
676 
691 l_ok
693  l_int32 index,
694  l_float32 *pval)
695 {
696  PROCNAME("numaGetFValue");
697 
698  if (!pval)
699  return ERROR_INT("&val not defined", procName, 1);
700  *pval = 0.0;
701  if (!na)
702  return ERROR_INT("na not defined", procName, 1);
703 
704  if (index < 0 || index >= na->n)
705  return ERROR_INT("index not valid", procName, 1);
706 
707  *pval = na->array[index];
708  return 0;
709 }
710 
711 
726 l_ok
728  l_int32 index,
729  l_int32 *pival)
730 {
731 l_float32 val;
732 
733  PROCNAME("numaGetIValue");
734 
735  if (!pival)
736  return ERROR_INT("&ival not defined", procName, 1);
737  *pival = 0;
738  if (!na)
739  return ERROR_INT("na not defined", procName, 1);
740 
741  if (index < 0 || index >= na->n)
742  return ERROR_INT("index not valid", procName, 1);
743 
744  val = na->array[index];
745  *pival = (l_int32)(val + L_SIGN(val) * 0.5);
746  return 0;
747 }
748 
749 
758 l_ok
760  l_int32 index,
761  l_float32 val)
762 {
763  PROCNAME("numaSetValue");
764 
765  if (!na)
766  return ERROR_INT("na not defined", procName, 1);
767  if (index < 0 || index >= na->n)
768  return ERROR_INT("index not valid", procName, 1);
769 
770  na->array[index] = val;
771  return 0;
772 }
773 
774 
783 l_ok
785  l_int32 index,
786  l_float32 diff)
787 {
788  PROCNAME("numaShiftValue");
789 
790  if (!na)
791  return ERROR_INT("na not defined", procName, 1);
792  if (index < 0 || index >= na->n)
793  return ERROR_INT("index not valid", procName, 1);
794 
795  na->array[index] += diff;
796  return 0;
797 }
798 
799 
819 l_int32 *
821 {
822 l_int32 i, n, ival;
823 l_int32 *array;
824 
825  PROCNAME("numaGetIArray");
826 
827  if (!na)
828  return (l_int32 *)ERROR_PTR("na not defined", procName, NULL);
829 
830  n = numaGetCount(na);
831  if ((array = (l_int32 *)LEPT_CALLOC(n, sizeof(l_int32))) == NULL)
832  return (l_int32 *)ERROR_PTR("array not made", procName, NULL);
833  for (i = 0; i < n; i++) {
834  numaGetIValue(na, i, &ival);
835  array[i] = ival;
836  }
837 
838  return array;
839 }
840 
841 
864 l_float32 *
866  l_int32 copyflag)
867 {
868 l_int32 i, n;
869 l_float32 *array;
870 
871  PROCNAME("numaGetFArray");
872 
873  if (!na)
874  return (l_float32 *)ERROR_PTR("na not defined", procName, NULL);
875 
876  if (copyflag == L_NOCOPY) {
877  array = na->array;
878  } else { /* copyflag == L_COPY */
879  n = numaGetCount(na);
880  if ((array = (l_float32 *)LEPT_CALLOC(n, sizeof(l_float32))) == NULL)
881  return (l_float32 *)ERROR_PTR("array not made", procName, NULL);
882  for (i = 0; i < n; i++)
883  array[i] = na->array[i];
884  }
885 
886  return array;
887 }
888 
889 
896 l_int32
898 {
899  PROCNAME("numaGetRefcount");
900 
901  if (!na)
902  return ERROR_INT("na not defined", procName, UNDEF);
903  return na->refcount;
904 }
905 
906 
914 l_ok
916  l_int32 delta)
917 {
918  PROCNAME("numaChangeRefcount");
919 
920  if (!na)
921  return ERROR_INT("na not defined", procName, 1);
922  na->refcount += delta;
923  return 0;
924 }
925 
926 
935 l_ok
937  l_float32 *pstartx,
938  l_float32 *pdelx)
939 {
940  PROCNAME("numaGetParameters");
941 
942  if (!pdelx && !pstartx)
943  return ERROR_INT("no return val requested", procName, 1);
944  if (pstartx) *pstartx = 0.0;
945  if (pdelx) *pdelx = 1.0;
946  if (!na)
947  return ERROR_INT("na not defined", procName, 1);
948 
949  if (pstartx) *pstartx = na->startx;
950  if (pdelx) *pdelx = na->delx;
951  return 0;
952 }
953 
954 
965 l_ok
967  l_float32 startx,
968  l_float32 delx)
969 {
970  PROCNAME("numaSetParameters");
971 
972  if (!na)
973  return ERROR_INT("na not defined", procName, 1);
974 
975  na->startx = startx;
976  na->delx = delx;
977  return 0;
978 }
979 
980 
988 l_ok
990  NUMA *nas)
991 {
992 l_float32 start, binsize;
993 
994  PROCNAME("numaCopyParameters");
995 
996  if (!nas || !nad)
997  return ERROR_INT("nas and nad not both defined", procName, 1);
998 
999  numaGetParameters(nas, &start, &binsize);
1000  numaSetParameters(nad, start, binsize);
1001  return 0;
1002 }
1003 
1004 
1005 /*----------------------------------------------------------------------*
1006  * Convert to string array *
1007  *----------------------------------------------------------------------*/
1026 SARRAY *
1028  l_int32 size1,
1029  l_int32 size2,
1030  l_int32 addzeros,
1031  l_int32 type)
1032 {
1033 char fmt[32], strbuf[64];
1034 l_int32 i, n, ival;
1035 l_float32 fval;
1036 SARRAY *sa;
1037 
1038  PROCNAME("numaConvertToSarray");
1039 
1040  if (!na)
1041  return (SARRAY *)ERROR_PTR("na not defined", procName, NULL);
1042  if (type != L_INTEGER_VALUE && type != L_FLOAT_VALUE)
1043  return (SARRAY *)ERROR_PTR("invalid type", procName, NULL);
1044 
1045  if (type == L_INTEGER_VALUE) {
1046  if (addzeros)
1047  snprintf(fmt, sizeof(fmt), "%%0%dd", size1);
1048  else
1049  snprintf(fmt, sizeof(fmt), "%%%dd", size1);
1050  } else { /* L_FLOAT_VALUE */
1051  snprintf(fmt, sizeof(fmt), "%%%d.%df", size1, size2);
1052  }
1053 
1054  n = numaGetCount(na);
1055  if ((sa = sarrayCreate(n)) == NULL)
1056  return (SARRAY *)ERROR_PTR("sa not made", procName, NULL);
1057 
1058  for (i = 0; i < n; i++) {
1059  if (type == L_INTEGER_VALUE) {
1060  numaGetIValue(na, i, &ival);
1061  snprintf(strbuf, sizeof(strbuf), fmt, ival);
1062  } else { /* L_FLOAT_VALUE */
1063  numaGetFValue(na, i, &fval);
1064  snprintf(strbuf, sizeof(strbuf), fmt, fval);
1065  }
1066  sarrayAddString(sa, strbuf, L_COPY);
1067  }
1068 
1069  return sa;
1070 }
1071 
1072 
1073 /*----------------------------------------------------------------------*
1074  * Serialize numa for I/O *
1075  *----------------------------------------------------------------------*/
1082 NUMA *
1083 numaRead(const char *filename)
1084 {
1085 FILE *fp;
1086 NUMA *na;
1087 
1088  PROCNAME("numaRead");
1089 
1090  if (!filename)
1091  return (NUMA *)ERROR_PTR("filename not defined", procName, NULL);
1092 
1093  if ((fp = fopenReadStream(filename)) == NULL)
1094  return (NUMA *)ERROR_PTR("stream not opened", procName, NULL);
1095  na = numaReadStream(fp);
1096  fclose(fp);
1097  if (!na)
1098  return (NUMA *)ERROR_PTR("na not read", procName, NULL);
1099  return na;
1100 }
1101 
1102 
1109 NUMA *
1111 {
1112 l_int32 i, n, index, ret, version;
1113 l_float32 val, startx, delx;
1114 NUMA *na;
1115 
1116  PROCNAME("numaReadStream");
1117 
1118  if (!fp)
1119  return (NUMA *)ERROR_PTR("stream not defined", procName, NULL);
1120 
1121  ret = fscanf(fp, "\nNuma Version %d\n", &version);
1122  if (ret != 1)
1123  return (NUMA *)ERROR_PTR("not a numa file", procName, NULL);
1124  if (version != NUMA_VERSION_NUMBER)
1125  return (NUMA *)ERROR_PTR("invalid numa version", procName, NULL);
1126  if (fscanf(fp, "Number of numbers = %d\n", &n) != 1)
1127  return (NUMA *)ERROR_PTR("invalid number of numbers", procName, NULL);
1128 
1129  if ((na = numaCreate(n)) == NULL)
1130  return (NUMA *)ERROR_PTR("na not made", procName, NULL);
1131 
1132  for (i = 0; i < n; i++) {
1133  if (fscanf(fp, " [%d] = %f\n", &index, &val) != 2) {
1134  numaDestroy(&na);
1135  return (NUMA *)ERROR_PTR("bad input data", procName, NULL);
1136  }
1137  numaAddNumber(na, val);
1138  }
1139 
1140  /* Optional data */
1141  if (fscanf(fp, "startx = %f, delx = %f\n", &startx, &delx) == 2)
1142  numaSetParameters(na, startx, delx);
1143 
1144  return na;
1145 }
1146 
1147 
1155 NUMA *
1156 numaReadMem(const l_uint8 *data,
1157  size_t size)
1158 {
1159 FILE *fp;
1160 NUMA *na;
1161 
1162  PROCNAME("numaReadMem");
1163 
1164  if (!data)
1165  return (NUMA *)ERROR_PTR("data not defined", procName, NULL);
1166  if ((fp = fopenReadFromMemory(data, size)) == NULL)
1167  return (NUMA *)ERROR_PTR("stream not opened", procName, NULL);
1168 
1169  na = numaReadStream(fp);
1170  fclose(fp);
1171  if (!na) L_ERROR("numa not read\n", procName);
1172  return na;
1173 }
1174 
1175 
1192 l_ok
1193 numaWriteDebug(const char *filename,
1194  NUMA *na)
1195 {
1196  PROCNAME("numaWriteDebug");
1197 
1198  if (LeptDebugOK) {
1199  return numaWrite(filename, na);
1200  } else {
1201  L_INFO("write to named temp file %s is disabled\n", procName, filename);
1202  return 0;
1203  }
1204 }
1205 
1206 
1214 l_ok
1215 numaWrite(const char *filename,
1216  NUMA *na)
1217 {
1218 l_int32 ret;
1219 FILE *fp;
1220 
1221  PROCNAME("numaWrite");
1222 
1223  if (!filename)
1224  return ERROR_INT("filename not defined", procName, 1);
1225  if (!na)
1226  return ERROR_INT("na not defined", procName, 1);
1227 
1228  if ((fp = fopenWriteStream(filename, "w")) == NULL)
1229  return ERROR_INT("stream not opened", procName, 1);
1230  ret = numaWriteStream(fp, na);
1231  fclose(fp);
1232  if (ret)
1233  return ERROR_INT("na not written to stream", procName, 1);
1234  return 0;
1235 }
1236 
1237 
1245 l_ok
1247  NUMA *na)
1248 {
1249 l_int32 i, n;
1250 l_float32 startx, delx;
1251 
1252  PROCNAME("numaWriteStream");
1253 
1254  if (!fp)
1255  return ERROR_INT("stream not defined", procName, 1);
1256  if (!na)
1257  return ERROR_INT("na not defined", procName, 1);
1258 
1259  n = numaGetCount(na);
1260  fprintf(fp, "\nNuma Version %d\n", NUMA_VERSION_NUMBER);
1261  fprintf(fp, "Number of numbers = %d\n", n);
1262  for (i = 0; i < n; i++)
1263  fprintf(fp, " [%d] = %f\n", i, na->array[i]);
1264  fprintf(fp, "\n");
1265 
1266  /* Optional data */
1267  numaGetParameters(na, &startx, &delx);
1268  if (startx != 0.0 || delx != 1.0)
1269  fprintf(fp, "startx = %f, delx = %f\n", startx, delx);
1270 
1271  return 0;
1272 }
1273 
1274 
1288 l_ok
1289 numaWriteMem(l_uint8 **pdata,
1290  size_t *psize,
1291  NUMA *na)
1292 {
1293 l_int32 ret;
1294 FILE *fp;
1295 
1296  PROCNAME("numaWriteMem");
1297 
1298  if (pdata) *pdata = NULL;
1299  if (psize) *psize = 0;
1300  if (!pdata)
1301  return ERROR_INT("&data not defined", procName, 1);
1302  if (!psize)
1303  return ERROR_INT("&size not defined", procName, 1);
1304  if (!na)
1305  return ERROR_INT("na not defined", procName, 1);
1306 
1307 #if HAVE_FMEMOPEN
1308  if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1309  return ERROR_INT("stream not opened", procName, 1);
1310  ret = numaWriteStream(fp, na);
1311 #else
1312  L_INFO("work-around: writing to a temp file\n", procName);
1313  #ifdef _WIN32
1314  if ((fp = fopenWriteWinTempfile()) == NULL)
1315  return ERROR_INT("tmpfile stream not opened", procName, 1);
1316  #else
1317  if ((fp = tmpfile()) == NULL)
1318  return ERROR_INT("tmpfile stream not opened", procName, 1);
1319  #endif /* _WIN32 */
1320  ret = numaWriteStream(fp, na);
1321  rewind(fp);
1322  *pdata = l_binaryReadStream(fp, psize);
1323 #endif /* HAVE_FMEMOPEN */
1324  fclose(fp);
1325  return ret;
1326 }
1327 
1328 
1329 /*--------------------------------------------------------------------------*
1330  * Numaa creation, destruction *
1331  *--------------------------------------------------------------------------*/
1339 NUMAA *
1340 numaaCreate(l_int32 n)
1341 {
1342 NUMAA *naa;
1343 
1344  PROCNAME("numaaCreate");
1345 
1346  if (n <= 0)
1347  n = INITIAL_PTR_ARRAYSIZE;
1348 
1349  if ((naa = (NUMAA *)LEPT_CALLOC(1, sizeof(NUMAA))) == NULL)
1350  return (NUMAA *)ERROR_PTR("naa not made", procName, NULL);
1351  if ((naa->numa = (NUMA **)LEPT_CALLOC(n, sizeof(NUMA *))) == NULL) {
1352  numaaDestroy(&naa);
1353  return (NUMAA *)ERROR_PTR("numa ptr array not made", procName, NULL);
1354  }
1355 
1356  naa->nalloc = n;
1357  naa->n = 0;
1358  return naa;
1359 }
1360 
1361 
1378 NUMAA *
1379 numaaCreateFull(l_int32 nptr,
1380  l_int32 n)
1381 {
1382 l_int32 i;
1383 NUMAA *naa;
1384 NUMA *na;
1385 
1386  naa = numaaCreate(nptr);
1387  for (i = 0; i < nptr; i++) {
1388  na = numaCreate(n);
1389  numaaAddNuma(naa, na, L_INSERT);
1390  }
1391 
1392  return naa;
1393 }
1394 
1395 
1409 l_ok
1411 {
1412 l_int32 i, n, nn;
1413 NUMA *na;
1414 
1415  PROCNAME("numaaTruncate");
1416 
1417  if (!naa)
1418  return ERROR_INT("naa not defined", procName, 1);
1419 
1420  n = numaaGetCount(naa);
1421  for (i = n - 1; i >= 0; i--) {
1422  na = numaaGetNuma(naa, i, L_CLONE);
1423  if (!na)
1424  continue;
1425  nn = numaGetCount(na);
1426  numaDestroy(&na);
1427  if (nn == 0)
1428  numaDestroy(&naa->numa[i]);
1429  else
1430  break;
1431  }
1432  naa->n = i + 1;
1433  return 0;
1434 }
1435 
1436 
1443 void
1445 {
1446 l_int32 i;
1447 NUMAA *naa;
1448 
1449  PROCNAME("numaaDestroy");
1450 
1451  if (pnaa == NULL) {
1452  L_WARNING("ptr address is NULL!\n", procName);
1453  return;
1454  }
1455 
1456  if ((naa = *pnaa) == NULL)
1457  return;
1458 
1459  for (i = 0; i < naa->n; i++)
1460  numaDestroy(&naa->numa[i]);
1461  LEPT_FREE(naa->numa);
1462  LEPT_FREE(naa);
1463  *pnaa = NULL;
1464 
1465  return;
1466 }
1467 
1468 
1469 
1470 /*--------------------------------------------------------------------------*
1471  * Add Numa to Numaa *
1472  *--------------------------------------------------------------------------*/
1481 l_ok
1483  NUMA *na,
1484  l_int32 copyflag)
1485 {
1486 l_int32 n;
1487 NUMA *nac;
1488 
1489  PROCNAME("numaaAddNuma");
1490 
1491  if (!naa)
1492  return ERROR_INT("naa not defined", procName, 1);
1493  if (!na)
1494  return ERROR_INT("na not defined", procName, 1);
1495 
1496  if (copyflag == L_INSERT) {
1497  nac = na;
1498  } else if (copyflag == L_COPY) {
1499  if ((nac = numaCopy(na)) == NULL)
1500  return ERROR_INT("nac not made", procName, 1);
1501  } else if (copyflag == L_CLONE) {
1502  nac = numaClone(na);
1503  } else {
1504  return ERROR_INT("invalid copyflag", procName, 1);
1505  }
1506 
1507  n = numaaGetCount(naa);
1508  if (n >= naa->nalloc)
1509  numaaExtendArray(naa);
1510  naa->numa[n] = nac;
1511  naa->n++;
1512  return 0;
1513 }
1514 
1515 
1522 static l_int32
1524 {
1525  PROCNAME("numaaExtendArray");
1526 
1527  if (!naa)
1528  return ERROR_INT("naa not defined", procName, 1);
1529 
1530  if ((naa->numa = (NUMA **)reallocNew((void **)&naa->numa,
1531  sizeof(NUMA *) * naa->nalloc,
1532  2 * sizeof(NUMA *) * naa->nalloc)) == NULL)
1533  return ERROR_INT("new ptr array not returned", procName, 1);
1534 
1535  naa->nalloc *= 2;
1536  return 0;
1537 }
1538 
1539 
1540 /*----------------------------------------------------------------------*
1541  * Numaa accessors *
1542  *----------------------------------------------------------------------*/
1549 l_int32
1551 {
1552  PROCNAME("numaaGetCount");
1553 
1554  if (!naa)
1555  return ERROR_INT("naa not defined", procName, 0);
1556  return naa->n;
1557 }
1558 
1559 
1567 l_int32
1569  l_int32 index)
1570 {
1571  PROCNAME("numaaGetNumaCount");
1572 
1573  if (!naa)
1574  return ERROR_INT("naa not defined", procName, 0);
1575  if (index < 0 || index >= naa->n)
1576  return ERROR_INT("invalid index into naa", procName, 0);
1577  return numaGetCount(naa->numa[index]);
1578 }
1579 
1580 
1588 l_int32
1590 {
1591 NUMA *na;
1592 l_int32 n, sum, i;
1593 
1594  PROCNAME("numaaGetNumberCount");
1595 
1596  if (!naa)
1597  return ERROR_INT("naa not defined", procName, 0);
1598 
1599  n = numaaGetCount(naa);
1600  for (sum = 0, i = 0; i < n; i++) {
1601  na = numaaGetNuma(naa, i, L_CLONE);
1602  sum += numaGetCount(na);
1603  numaDestroy(&na);
1604  }
1605 
1606  return sum;
1607 }
1608 
1609 
1637 NUMA **
1639 {
1640  PROCNAME("numaaGetPtrArray");
1641 
1642  if (!naa)
1643  return (NUMA **)ERROR_PTR("naa not defined", procName, NULL);
1644 
1645  naa->n = naa->nalloc;
1646  return naa->numa;
1647 }
1648 
1649 
1658 NUMA *
1660  l_int32 index,
1661  l_int32 accessflag)
1662 {
1663  PROCNAME("numaaGetNuma");
1664 
1665  if (!naa)
1666  return (NUMA *)ERROR_PTR("naa not defined", procName, NULL);
1667  if (index < 0 || index >= naa->n)
1668  return (NUMA *)ERROR_PTR("index not valid", procName, NULL);
1669 
1670  if (accessflag == L_COPY)
1671  return numaCopy(naa->numa[index]);
1672  else if (accessflag == L_CLONE)
1673  return numaClone(naa->numa[index]);
1674  else
1675  return (NUMA *)ERROR_PTR("invalid accessflag", procName, NULL);
1676 }
1677 
1678 
1694 l_ok
1696  l_int32 index,
1697  NUMA *na)
1698 {
1699 l_int32 n;
1700 
1701  PROCNAME("numaaReplaceNuma");
1702 
1703  if (!naa)
1704  return ERROR_INT("naa not defined", procName, 1);
1705  if (!na)
1706  return ERROR_INT("na not defined", procName, 1);
1707  n = numaaGetCount(naa);
1708  if (index < 0 || index >= n)
1709  return ERROR_INT("index not valid", procName, 1);
1710 
1711  numaDestroy(&naa->numa[index]);
1712  naa->numa[index] = na;
1713  return 0;
1714 }
1715 
1716 
1727 l_ok
1729  l_int32 i,
1730  l_int32 j,
1731  l_float32 *pfval,
1732  l_int32 *pival)
1733 {
1734 l_int32 n;
1735 NUMA *na;
1736 
1737  PROCNAME("numaaGetValue");
1738 
1739  if (!pfval && !pival)
1740  return ERROR_INT("no return val requested", procName, 1);
1741  if (pfval) *pfval = 0.0;
1742  if (pival) *pival = 0;
1743  if (!naa)
1744  return ERROR_INT("naa not defined", procName, 1);
1745  n = numaaGetCount(naa);
1746  if (i < 0 || i >= n)
1747  return ERROR_INT("invalid index into naa", procName, 1);
1748  na = naa->numa[i];
1749  if (j < 0 || j >= na->n)
1750  return ERROR_INT("invalid index into na", procName, 1);
1751  if (pfval) *pfval = na->array[j];
1752  if (pival) *pival = (l_int32)(na->array[j]);
1753  return 0;
1754 }
1755 
1756 
1770 l_ok
1772  l_int32 index,
1773  l_float32 val)
1774 {
1775 l_int32 n;
1776 NUMA *na;
1777 
1778  PROCNAME("numaaAddNumber");
1779 
1780  if (!naa)
1781  return ERROR_INT("naa not defined", procName, 1);
1782  n = numaaGetCount(naa);
1783  if (index < 0 || index >= n)
1784  return ERROR_INT("invalid index in naa", procName, 1);
1785 
1786  na = numaaGetNuma(naa, index, L_CLONE);
1787  numaAddNumber(na, val);
1788  numaDestroy(&na);
1789  return 0;
1790 }
1791 
1792 
1793 /*----------------------------------------------------------------------*
1794  * Serialize numaa for I/O *
1795  *----------------------------------------------------------------------*/
1802 NUMAA *
1803 numaaRead(const char *filename)
1804 {
1805 FILE *fp;
1806 NUMAA *naa;
1807 
1808  PROCNAME("numaaRead");
1809 
1810  if (!filename)
1811  return (NUMAA *)ERROR_PTR("filename not defined", procName, NULL);
1812 
1813  if ((fp = fopenReadStream(filename)) == NULL)
1814  return (NUMAA *)ERROR_PTR("stream not opened", procName, NULL);
1815  naa = numaaReadStream(fp);
1816  fclose(fp);
1817  if (!naa)
1818  return (NUMAA *)ERROR_PTR("naa not read", procName, NULL);
1819  return naa;
1820 }
1821 
1822 
1829 NUMAA *
1831 {
1832 l_int32 i, n, index, ret, version;
1833 NUMA *na;
1834 NUMAA *naa;
1835 
1836  PROCNAME("numaaReadStream");
1837 
1838  if (!fp)
1839  return (NUMAA *)ERROR_PTR("stream not defined", procName, NULL);
1840 
1841  ret = fscanf(fp, "\nNumaa Version %d\n", &version);
1842  if (ret != 1)
1843  return (NUMAA *)ERROR_PTR("not a numa file", procName, NULL);
1844  if (version != NUMA_VERSION_NUMBER)
1845  return (NUMAA *)ERROR_PTR("invalid numaa version", procName, NULL);
1846  if (fscanf(fp, "Number of numa = %d\n\n", &n) != 1)
1847  return (NUMAA *)ERROR_PTR("invalid number of numa", procName, NULL);
1848  if ((naa = numaaCreate(n)) == NULL)
1849  return (NUMAA *)ERROR_PTR("naa not made", procName, NULL);
1850 
1851  for (i = 0; i < n; i++) {
1852  if (fscanf(fp, "Numa[%d]:", &index) != 1) {
1853  numaaDestroy(&naa);
1854  return (NUMAA *)ERROR_PTR("invalid numa header", procName, NULL);
1855  }
1856  if ((na = numaReadStream(fp)) == NULL) {
1857  numaaDestroy(&naa);
1858  return (NUMAA *)ERROR_PTR("na not made", procName, NULL);
1859  }
1860  numaaAddNuma(naa, na, L_INSERT);
1861  }
1862 
1863  return naa;
1864 }
1865 
1866 
1874 NUMAA *
1875 numaaReadMem(const l_uint8 *data,
1876  size_t size)
1877 {
1878 FILE *fp;
1879 NUMAA *naa;
1880 
1881  PROCNAME("numaaReadMem");
1882 
1883  if (!data)
1884  return (NUMAA *)ERROR_PTR("data not defined", procName, NULL);
1885  if ((fp = fopenReadFromMemory(data, size)) == NULL)
1886  return (NUMAA *)ERROR_PTR("stream not opened", procName, NULL);
1887 
1888  naa = numaaReadStream(fp);
1889  fclose(fp);
1890  if (!naa) L_ERROR("naa not read\n", procName);
1891  return naa;
1892 }
1893 
1894 
1902 l_ok
1903 numaaWrite(const char *filename,
1904  NUMAA *naa)
1905 {
1906 l_int32 ret;
1907 FILE *fp;
1908 
1909  PROCNAME("numaaWrite");
1910 
1911  if (!filename)
1912  return ERROR_INT("filename not defined", procName, 1);
1913  if (!naa)
1914  return ERROR_INT("naa not defined", procName, 1);
1915 
1916  if ((fp = fopenWriteStream(filename, "w")) == NULL)
1917  return ERROR_INT("stream not opened", procName, 1);
1918  ret = numaaWriteStream(fp, naa);
1919  fclose(fp);
1920  if (ret)
1921  return ERROR_INT("naa not written to stream", procName, 1);
1922  return 0;
1923 }
1924 
1925 
1933 l_ok
1935  NUMAA *naa)
1936 {
1937 l_int32 i, n;
1938 NUMA *na;
1939 
1940  PROCNAME("numaaWriteStream");
1941 
1942  if (!fp)
1943  return ERROR_INT("stream not defined", procName, 1);
1944  if (!naa)
1945  return ERROR_INT("naa not defined", procName, 1);
1946 
1947  n = numaaGetCount(naa);
1948  fprintf(fp, "\nNumaa Version %d\n", NUMA_VERSION_NUMBER);
1949  fprintf(fp, "Number of numa = %d\n\n", n);
1950  for (i = 0; i < n; i++) {
1951  if ((na = numaaGetNuma(naa, i, L_CLONE)) == NULL)
1952  return ERROR_INT("na not found", procName, 1);
1953  fprintf(fp, "Numa[%d]:", i);
1954  numaWriteStream(fp, na);
1955  numaDestroy(&na);
1956  }
1957 
1958  return 0;
1959 }
1960 
1961 
1975 l_ok
1976 numaaWriteMem(l_uint8 **pdata,
1977  size_t *psize,
1978  NUMAA *naa)
1979 {
1980 l_int32 ret;
1981 FILE *fp;
1982 
1983  PROCNAME("numaaWriteMem");
1984 
1985  if (pdata) *pdata = NULL;
1986  if (psize) *psize = 0;
1987  if (!pdata)
1988  return ERROR_INT("&data not defined", procName, 1);
1989  if (!psize)
1990  return ERROR_INT("&size not defined", procName, 1);
1991  if (!naa)
1992  return ERROR_INT("naa not defined", procName, 1);
1993 
1994 #if HAVE_FMEMOPEN
1995  if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1996  return ERROR_INT("stream not opened", procName, 1);
1997  ret = numaaWriteStream(fp, naa);
1998 #else
1999  L_INFO("work-around: writing to a temp file\n", procName);
2000  #ifdef _WIN32
2001  if ((fp = fopenWriteWinTempfile()) == NULL)
2002  return ERROR_INT("tmpfile stream not opened", procName, 1);
2003  #else
2004  if ((fp = tmpfile()) == NULL)
2005  return ERROR_INT("tmpfile stream not opened", procName, 1);
2006  #endif /* _WIN32 */
2007  ret = numaaWriteStream(fp, naa);
2008  rewind(fp);
2009  *pdata = l_binaryReadStream(fp, psize);
2010 #endif /* HAVE_FMEMOPEN */
2011  fclose(fp);
2012  return ret;
2013 }
2014 
NUMAA * numaaReadMem(const l_uint8 *data, size_t size)
numaaReadMem()
Definition: numabasic.c:1875
NUMAA * numaaRead(const char *filename)
numaaRead()
Definition: numabasic.c:1803
l_ok numaGetFValue(NUMA *na, l_int32 index, l_float32 *pval)
numaGetFValue()
Definition: numabasic.c:692
NUMAA * numaaReadStream(FILE *fp)
numaaReadStream()
Definition: numabasic.c:1830
Definition: pix.h:717
NUMA * numaReadMem(const l_uint8 *data, size_t size)
numaReadMem()
Definition: numabasic.c:1156
l_float32 ** data
Definition: morph.h:95
struct Numa ** numa
Definition: array.h:75
NUMA ** numaaGetPtrArray(NUMAA *naa)
numaaGetPtrArray()
Definition: numabasic.c:1638
NUMA * numaRead(const char *filename)
numaRead()
Definition: numabasic.c:1083
l_ok numaInsertNumber(NUMA *na, l_int32 index, l_float32 val)
numaInsertNumber()
Definition: numabasic.c:534
l_ok numaWriteDebug(const char *filename, NUMA *na)
numaWriteDebug()
Definition: numabasic.c:1193
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:473
l_int32 numaaGetNumberCount(NUMAA *naa)
numaaGetNumberCount()
Definition: numabasic.c:1589
Definition: pix.h:716
l_ok numaWriteMem(l_uint8 **pdata, size_t *psize, NUMA *na)
numaWriteMem()
Definition: numabasic.c:1289
l_int32 nalloc
Definition: array.h:73
l_int32 refcount
Definition: array.h:63
l_ok numaCopyParameters(NUMA *nad, NUMA *nas)
numaCopyParameters()
Definition: numabasic.c:989
l_float32 startx
Definition: array.h:64
l_int32 nalloc
Definition: array.h:61
SARRAY * sarrayCreate(l_int32 n)
sarrayCreate()
Definition: sarray1.c:163
FILE * fopenReadFromMemory(const l_uint8 *data, size_t size)
fopenReadFromMemory()
Definition: utils2.c:1734
l_ok numaWriteStream(FILE *fp, NUMA *na)
numaWriteStream()
Definition: numabasic.c:1246
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:187
l_float32 delx
Definition: array.h:65
l_ok numaSetCount(NUMA *na, l_int32 newcount)
numaSetCount()
Definition: numabasic.c:658
NUMAA * numaaCreate(l_int32 n)
numaaCreate()
Definition: numabasic.c:1340
void * reallocNew(void **pindata, l_int32 oldsize, l_int32 newsize)
reallocNew()
Definition: utils2.c:1161
l_ok numaSetValue(NUMA *na, l_int32 index, l_float32 val)
numaSetValue()
Definition: numabasic.c:759
void numaaDestroy(NUMAA **pnaa)
numaaDestroy()
Definition: numabasic.c:1444
l_ok numaaWriteStream(FILE *fp, NUMAA *naa)
numaaWriteStream()
Definition: numabasic.c:1934
Definition: array.h:116
l_int32 numaGetRefcount(NUMA *na)
numaGetRefCount()
Definition: numabasic.c:897
l_int32 * numaGetIArray(NUMA *na)
numaGetIArray()
Definition: numabasic.c:820
NUMA * numaaGetNuma(NUMAA *naa, l_int32 index, l_int32 accessflag)
numaaGetNuma()
Definition: numabasic.c:1659
l_ok numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition: numabasic.c:727
Definition: array.h:59
l_int32 numaGetCount(NUMA *na)
numaGetCount()
Definition: numabasic.c:631
l_ok sarrayAddString(SARRAY *sa, const char *string, l_int32 copyflag)
sarrayAddString()
Definition: sarray1.c:446
l_ok numaWrite(const char *filename, NUMA *na)
numaWrite()
Definition: numabasic.c:1215
l_float32 * array
Definition: array.h:66
l_ok numaRemoveNumber(NUMA *na, l_int32 index)
numaRemoveNumber()
Definition: numabasic.c:573
FILE * fopenWriteWinTempfile()
fopenWriteWinTempfile()
Definition: utils2.c:1780
char * sarrayGetString(SARRAY *sa, l_int32 index, l_int32 copyflag)
sarrayGetString()
Definition: sarray1.c:681
l_ok numaSetParameters(NUMA *na, l_float32 startx, l_float32 delx)
numaSetParameters()
Definition: numabasic.c:966
l_ok numaGetParameters(NUMA *na, l_float32 *pstartx, l_float32 *pdelx)
numaGetParameters()
Definition: numabasic.c:936
l_ok numaEmpty(NUMA *na)
numaEmpty()
Definition: numabasic.c:449
Definition: array.h:71
NUMA * numaCreateFromIArray(l_int32 *iarray, l_int32 size)
numaCreateFromIArray()
Definition: numabasic.c:228
l_ok numaaTruncate(NUMAA *naa)
numaaTruncate()
Definition: numabasic.c:1410
l_ok numaChangeRefcount(NUMA *na, l_int32 delta)
numaChangeRefCount()
Definition: numabasic.c:915
l_ok numaaReplaceNuma(NUMAA *naa, l_int32 index, NUMA *na)
numaaReplaceNuma()
Definition: numabasic.c:1695
l_ok numaShiftValue(NUMA *na, l_int32 index, l_float32 diff)
numaShiftValue()
Definition: numabasic.c:784
l_ok numaaAddNumber(NUMAA *naa, l_int32 index, l_float32 val)
numaaAddNumber()
Definition: numabasic.c:1771
NUMA * numaCopy(NUMA *na)
numaCopy()
Definition: numabasic.c:394
NUMA * numaCreateFromString(const char *str)
numaCreateFromString()
Definition: numabasic.c:309
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:360
#define NUMA_VERSION_NUMBER
Definition: array.h:56
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1700
l_ok numaaGetValue(NUMAA *naa, l_int32 i, l_int32 j, l_float32 *pfval, l_int32 *pival)
numaaGetValue()
Definition: numabasic.c:1728
FILE * fopenReadStream(const char *filename)
fopenReadStream()
Definition: utils2.c:1657
l_uint8 * l_binaryReadStream(FILE *fp, size_t *pnbytes)
l_binaryReadStream()
Definition: utils2.c:1262
l_int32 sarrayGetCount(SARRAY *sa)
sarrayGetCount()
Definition: sarray1.c:621
l_int32 n
Definition: array.h:74
l_ok numaaWrite(const char *filename, NUMAA *naa)
numaaWrite()
Definition: numabasic.c:1903
l_float32 * numaGetFArray(NUMA *na, l_int32 copyflag)
numaGetFArray()
Definition: numabasic.c:865
l_int32 n
Definition: array.h:62
l_int32 numaaGetCount(NUMAA *naa)
numaaGetCount()
Definition: numabasic.c:1550
l_int32 numaaGetNumaCount(NUMAA *naa, l_int32 index)
numaaGetNumaCount()
Definition: numabasic.c:1568
Definition: pix.h:718
static l_int32 numaExtendArray(NUMA *na)
numaExtendArray()
Definition: numabasic.c:499
Definition: pix.h:719
static l_int32 numaaExtendArray(NUMAA *naa)
numaaExtendArray()
Definition: numabasic.c:1523
l_ok numaReplaceNumber(NUMA *na, l_int32 index, l_float32 val)
numaReplaceNumber()
Definition: numabasic.c:602
NUMA * numaClone(NUMA *na)
numaClone()
Definition: numabasic.c:423
NUMAA * numaaCreateFull(l_int32 nptr, l_int32 n)
numaaCreateFull()
Definition: numabasic.c:1379
NUMA * numaCreateFromFArray(l_float32 *farray, l_int32 size, l_int32 copyflag)
numaCreateFromFArray()
Definition: numabasic.c:265
SARRAY * numaConvertToSarray(NUMA *na, l_int32 size1, l_int32 size2, l_int32 addzeros, l_int32 type)
numaConvertToSarray()
Definition: numabasic.c:1027
l_ok numaaAddNuma(NUMAA *naa, NUMA *na, l_int32 copyflag)
numaaAddNuma()
Definition: numabasic.c:1482
l_ok numaaWriteMem(l_uint8 **pdata, size_t *psize, NUMAA *naa)
numaaWriteMem()
Definition: numabasic.c:1976
NUMA * numaReadStream(FILE *fp)
numaReadStream()
Definition: numabasic.c:1110
void sarrayDestroy(SARRAY **psa)
sarrayDestroy()
Definition: sarray1.c:355