Leptonica 1.85.0
Image processing and image analysis suite
Loading...
Searching...
No Matches
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
165#ifdef HAVE_CONFIG_H
166#include <config_auto.h>
167#endif /* HAVE_CONFIG_H */
168
169#include <string.h>
170#include <math.h>
171#include "allheaders.h"
172#include "array_internal.h"
173
174 /* Bounds on initial array size */
175static const l_uint32 MaxFloatArraySize = 100000000; /* for numa */
176static const l_uint32 MaxPtrArraySize = 1000000; /* for numaa */
177static const l_int32 InitialArraySize = 50;
179 /* Static functions */
180static l_int32 numaExtendArray(NUMA *na);
181static l_int32 numaaExtendArray(NUMAA *naa);
182
183/*--------------------------------------------------------------------------*
184 * Numa creation, destruction, copy, clone, etc. *
185 *--------------------------------------------------------------------------*/
192NUMA *
193numaCreate(l_int32 n)
194{
195NUMA *na;
196
197 if (n <= 0 || n > MaxFloatArraySize)
199
200 na = (NUMA *)LEPT_CALLOC(1, sizeof(NUMA));
201 if ((na->array = (l_float32 *)LEPT_CALLOC(n, sizeof(l_float32))) == NULL) {
202 numaDestroy(&na);
203 return (NUMA *)ERROR_PTR("number array not made", __func__, NULL);
204 }
205
206 na->nalloc = n;
207 na->n = 0;
208 na->refcount = 1;
209 na->startx = 0.0;
210 na->delx = 1.0;
211 return na;
212}
213
214
230NUMA *
231numaCreateFromIArray(l_int32 *iarray,
232 l_int32 size)
233{
234l_int32 i;
235NUMA *na;
236
237 if (!iarray)
238 return (NUMA *)ERROR_PTR("iarray not defined", __func__, NULL);
239 if (size <= 0)
240 return (NUMA *)ERROR_PTR("size must be > 0", __func__, NULL);
241
242 na = numaCreate(size);
243 for (i = 0; i < size; i++)
244 numaAddNumber(na, iarray[i]);
245
246 return na;
247}
248
249
265NUMA *
266numaCreateFromFArray(l_float32 *farray,
267 l_int32 size,
268 l_int32 copyflag)
269{
270l_int32 i;
271NUMA *na;
272
273 if (!farray)
274 return (NUMA *)ERROR_PTR("farray not defined", __func__, NULL);
275 if (size <= 0)
276 return (NUMA *)ERROR_PTR("size must be > 0", __func__, NULL);
277 if (copyflag != L_INSERT && copyflag != L_COPY)
278 return (NUMA *)ERROR_PTR("invalid copyflag", __func__, NULL);
279
280 na = numaCreate(size);
281 if (copyflag == L_INSERT) {
282 if (na->array) LEPT_FREE(na->array);
283 na->array = farray;
284 na->n = size;
285 } else { /* just copy the contents */
286 for (i = 0; i < size; i++)
287 numaAddNumber(na, farray[i]);
288 }
289
290 return na;
291}
292
293
307NUMA *
308numaCreateFromString(const char *str)
309{
310char *substr;
311l_int32 i, n, nerrors;
312l_float32 val;
313NUMA *na;
314SARRAY *sa;
315
316 if (!str || (strlen(str) == 0))
317 return (NUMA *)ERROR_PTR("str not defined or empty", __func__, NULL);
318
319 sa = sarrayCreate(0);
320 sarraySplitString(sa, str, ",");
321 n = sarrayGetCount(sa);
322 na = numaCreate(n);
323 nerrors = 0;
324 for (i = 0; i < n; i++) {
325 substr = sarrayGetString(sa, i, L_NOCOPY);
326 if (sscanf(substr, "%f", &val) != 1) {
327 L_ERROR("substr %d not float\n", __func__, i);
328 nerrors++;
329 } else {
330 numaAddNumber(na, val);
331 }
332 }
333
334 sarrayDestroy(&sa);
335 if (nerrors > 0) {
336 numaDestroy(&na);
337 return (NUMA *)ERROR_PTR("non-floats in string", __func__, NULL);
338 }
339
340 return na;
341}
342
343
356void
358{
359NUMA *na;
360
361 if (pna == NULL) {
362 L_WARNING("ptr address is NULL\n", __func__);
363 return;
364 }
365
366 if ((na = *pna) == NULL)
367 return;
368
369 /* Decrement the ref count. If it is 0, destroy the numa. */
370 if (--na->refcount == 0) {
371 if (na->array)
372 LEPT_FREE(na->array);
373 LEPT_FREE(na);
374 }
375
376 *pna = NULL;
377}
378
379
386NUMA *
388{
389l_int32 i;
390NUMA *cna;
391
392 if (!na)
393 return (NUMA *)ERROR_PTR("na not defined", __func__, NULL);
394
395 if ((cna = numaCreate(na->nalloc)) == NULL)
396 return (NUMA *)ERROR_PTR("cna not made", __func__, NULL);
397 cna->startx = na->startx;
398 cna->delx = na->delx;
399
400 for (i = 0; i < na->n; i++)
401 numaAddNumber(cna, na->array[i]);
402
403 return cna;
404}
405
406
413NUMA *
415{
416 if (!na)
417 return (NUMA *)ERROR_PTR("na not defined", __func__, NULL);
418
419 ++na->refcount;
420 return na;
421}
422
423
437l_ok
439{
440 if (!na)
441 return ERROR_INT("na not defined", __func__, 1);
442
443 na->n = 0;
444 return 0;
445}
446
447
448
449/*--------------------------------------------------------------------------*
450 * Number array: add number and extend array *
451 *--------------------------------------------------------------------------*/
459l_ok
461 l_float32 val)
462{
463l_int32 n;
464
465 if (!na)
466 return ERROR_INT("na not defined", __func__, 1);
467
468 n = numaGetCount(na);
469 if (n >= na->nalloc) {
470 if (numaExtendArray(na))
471 return ERROR_INT("extension failed", __func__, 1);
472 }
473 na->array[n] = val;
474 na->n++;
475 return 0;
476}
477
478
490static l_int32
492{
493size_t oldsize, newsize;
494
495 if (!na)
496 return ERROR_INT("na not defined", __func__, 1);
497 if (na->nalloc > MaxFloatArraySize) /* belt & suspenders */
498 return ERROR_INT("na has too many ptrs", __func__, 1);
499 oldsize = na->nalloc * sizeof(l_float32);
500 newsize = 2 * oldsize;
501 if (newsize > 4 * MaxFloatArraySize)
502 return ERROR_INT("newsize > 400 MB; too large", __func__, 1);
503
504 if ((na->array = (l_float32 *)reallocNew((void **)&na->array,
505 oldsize, newsize)) == NULL)
506 return ERROR_INT("new ptr array not returned", __func__, 1);
507
508 na->nalloc *= 2;
509 return 0;
510}
511
512
530l_ok
532 l_int32 index,
533 l_float32 val)
534{
535l_int32 i, n;
536
537 if (!na)
538 return ERROR_INT("na not defined", __func__, 1);
539 n = numaGetCount(na);
540 if (index < 0 || index > n) {
541 L_ERROR("index %d not in [0,...,%d]\n", __func__, index, n);
542 return 1;
543 }
544
545 if (n >= na->nalloc) {
546 if (numaExtendArray(na))
547 return ERROR_INT("extension failed", __func__, 1);
548 }
549 for (i = n; i > index; i--)
550 na->array[i] = na->array[i - 1];
551 na->array[index] = val;
552 na->n++;
553 return 0;
554}
555
556
571l_ok
573 l_int32 index)
574{
575l_int32 i, n;
576
577 if (!na)
578 return ERROR_INT("na not defined", __func__, 1);
579 n = numaGetCount(na);
580 if (index < 0 || index >= n) {
581 L_ERROR("index %d not in [0,...,%d]\n", __func__, index, n - 1);
582 return 1;
583 }
584
585 for (i = index + 1; i < n; i++)
586 na->array[i - 1] = na->array[i];
587 na->n--;
588 return 0;
589}
590
591
600l_ok
602 l_int32 index,
603 l_float32 val)
604{
605l_int32 n;
606
607 if (!na)
608 return ERROR_INT("na not defined", __func__, 1);
609 n = numaGetCount(na);
610 if (index < 0 || index >= n) {
611 L_ERROR("index %d not in [0,...,%d]\n", __func__, index, n - 1);
612 return 1;
613 }
614
615 na->array[index] = val;
616 return 0;
617}
618
619
620/*----------------------------------------------------------------------*
621 * Numa accessors *
622 *----------------------------------------------------------------------*/
629l_int32
631{
632 if (!na)
633 return ERROR_INT("na not defined", __func__, 0);
634 return na->n;
635}
636
637
654l_ok
656 l_int32 newcount)
657{
658 if (!na)
659 return ERROR_INT("na not defined", __func__, 1);
660 if (newcount > na->nalloc) {
661 if ((na->array = (l_float32 *)reallocNew((void **)&na->array,
662 sizeof(l_float32) * na->nalloc,
663 sizeof(l_float32) * newcount)) == NULL)
664 return ERROR_INT("new ptr array not returned", __func__, 1);
665 na->nalloc = newcount;
666 }
667 na->n = newcount;
668 return 0;
669}
670
671
686l_ok
688 l_int32 index,
689 l_float32 *pval)
690{
691 if (!pval)
692 return ERROR_INT("&val not defined", __func__, 1);
693 *pval = 0.0;
694 if (!na)
695 return ERROR_INT("na not defined", __func__, 1);
696
697 if (index < 0 || index >= na->n)
698 return ERROR_INT("index not valid", __func__, 1);
699
700 *pval = na->array[index];
701 return 0;
702}
703
704
719l_ok
721 l_int32 index,
722 l_int32 *pival)
723{
724l_float32 val;
725
726 if (!pival)
727 return ERROR_INT("&ival not defined", __func__, 1);
728 *pival = 0;
729 if (!na)
730 return ERROR_INT("na not defined", __func__, 1);
731
732 if (index < 0 || index >= na->n)
733 return ERROR_INT("index not valid", __func__, 1);
734
735 val = na->array[index];
736 *pival = (l_int32)(val + L_SIGN(val) * 0.5);
737 return 0;
738}
739
740
749l_ok
751 l_int32 index,
752 l_float32 val)
753{
754 if (!na)
755 return ERROR_INT("na not defined", __func__, 1);
756 if (index < 0 || index >= na->n)
757 return ERROR_INT("index not valid", __func__, 1);
758
759 na->array[index] = val;
760 return 0;
761}
762
763
772l_ok
774 l_int32 index,
775 l_float32 diff)
776{
777 if (!na)
778 return ERROR_INT("na not defined", __func__, 1);
779 if (index < 0 || index >= na->n)
780 return ERROR_INT("index not valid", __func__, 1);
781
782 na->array[index] += diff;
783 return 0;
784}
785
786
806l_int32 *
808{
809l_int32 i, n, ival;
810l_int32 *array;
811
812 if (!na)
813 return (l_int32 *)ERROR_PTR("na not defined", __func__, NULL);
814
815 if ((n = numaGetCount(na)) == 0)
816 return (l_int32 *)ERROR_PTR("na is empty", __func__, NULL);
817 if ((array = (l_int32 *)LEPT_CALLOC(n, sizeof(l_int32))) == NULL)
818 return (l_int32 *)ERROR_PTR("array not made", __func__, NULL);
819 for (i = 0; i < n; i++) {
820 numaGetIValue(na, i, &ival);
821 array[i] = ival;
822 }
823
824 return array;
825}
826
827
850l_float32 *
852 l_int32 copyflag)
853{
854l_int32 i, n;
855l_float32 *array;
856
857 if (!na)
858 return (l_float32 *)ERROR_PTR("na not defined", __func__, NULL);
859
860 if (copyflag == L_NOCOPY) {
861 array = na->array;
862 } else { /* copyflag == L_COPY */
863 if ((n = numaGetCount(na)) == 0)
864 return (l_float32 *)ERROR_PTR("na is empty", __func__, NULL);
865 if ((array = (l_float32 *)LEPT_CALLOC(n, sizeof(l_float32))) == NULL)
866 return (l_float32 *)ERROR_PTR("array not made", __func__, NULL);
867 for (i = 0; i < n; i++)
868 array[i] = na->array[i];
869 }
870
871 return array;
872}
873
874
883l_ok
885 l_float32 *pstartx,
886 l_float32 *pdelx)
887{
888 if (!pdelx && !pstartx)
889 return ERROR_INT("no return val requested", __func__, 1);
890 if (pstartx) *pstartx = 0.0;
891 if (pdelx) *pdelx = 1.0;
892 if (!na)
893 return ERROR_INT("na not defined", __func__, 1);
894
895 if (pstartx) *pstartx = na->startx;
896 if (pdelx) *pdelx = na->delx;
897 return 0;
898}
899
900
911l_ok
913 l_float32 startx,
914 l_float32 delx)
915{
916 if (!na)
917 return ERROR_INT("na not defined", __func__, 1);
918
919 na->startx = startx;
920 na->delx = delx;
921 return 0;
922}
923
924
932l_ok
934 NUMA *nas)
935{
936l_float32 start, binsize;
937
938 if (!nas || !nad)
939 return ERROR_INT("nas and nad not both defined", __func__, 1);
940
941 numaGetParameters(nas, &start, &binsize);
942 numaSetParameters(nad, start, binsize);
943 return 0;
944}
945
946
947/*----------------------------------------------------------------------*
948 * Convert to string array *
949 *----------------------------------------------------------------------*/
968SARRAY *
970 l_int32 size1,
971 l_int32 size2,
972 l_int32 addzeros,
973 l_int32 type)
974{
975char fmt[32], strbuf[64];
976l_int32 i, n, ival;
977l_float32 fval;
978SARRAY *sa;
979
980 if (!na)
981 return (SARRAY *)ERROR_PTR("na not defined", __func__, NULL);
982 if (type != L_INTEGER_VALUE && type != L_FLOAT_VALUE)
983 return (SARRAY *)ERROR_PTR("invalid type", __func__, NULL);
984
985 if (type == L_INTEGER_VALUE) {
986 if (addzeros)
987 snprintf(fmt, sizeof(fmt), "%%0%dd", size1);
988 else
989 snprintf(fmt, sizeof(fmt), "%%%dd", size1);
990 } else { /* L_FLOAT_VALUE */
991 snprintf(fmt, sizeof(fmt), "%%%d.%df", size1, size2);
992 }
993
994 n = numaGetCount(na);
995 if ((sa = sarrayCreate(n)) == NULL)
996 return (SARRAY *)ERROR_PTR("sa not made", __func__, NULL);
997
998 for (i = 0; i < n; i++) {
999 if (type == L_INTEGER_VALUE) {
1000 numaGetIValue(na, i, &ival);
1001 snprintf(strbuf, sizeof(strbuf), fmt, ival);
1002 } else { /* L_FLOAT_VALUE */
1003 numaGetFValue(na, i, &fval);
1004 snprintf(strbuf, sizeof(strbuf), fmt, fval);
1005 }
1006 sarrayAddString(sa, strbuf, L_COPY);
1007 }
1008
1009 return sa;
1010}
1011
1012
1013/*----------------------------------------------------------------------*
1014 * Serialize numa for I/O *
1015 *----------------------------------------------------------------------*/
1022NUMA *
1023numaRead(const char *filename)
1024{
1025FILE *fp;
1026NUMA *na;
1027
1028 if (!filename)
1029 return (NUMA *)ERROR_PTR("filename not defined", __func__, NULL);
1030
1031 if ((fp = fopenReadStream(filename)) == NULL)
1032 return (NUMA *)ERROR_PTR_1("stream not opened",
1033 filename, __func__, NULL);
1034 na = numaReadStream(fp);
1035 fclose(fp);
1036 if (!na)
1037 return (NUMA *)ERROR_PTR_1("na not read",
1038 filename, __func__, NULL);
1039 return na;
1040}
1041
1042
1049NUMA *
1051{
1052l_int32 i, n, index, ret, version;
1053l_float32 val, startx, delx;
1054NUMA *na;
1055
1056 if (!fp)
1057 return (NUMA *)ERROR_PTR("stream not defined", __func__, NULL);
1058
1059 ret = fscanf(fp, "\nNuma Version %d\n", &version);
1060 if (ret != 1)
1061 return (NUMA *)ERROR_PTR("not a numa file", __func__, NULL);
1062 if (version != NUMA_VERSION_NUMBER)
1063 return (NUMA *)ERROR_PTR("invalid numa version", __func__, NULL);
1064 if (fscanf(fp, "Number of numbers = %d\n", &n) != 1)
1065 return (NUMA *)ERROR_PTR("invalid number of numbers", __func__, NULL);
1066
1067 if (n > MaxFloatArraySize) {
1068 L_ERROR("n = %d > %d\n", __func__, n, MaxFloatArraySize);
1069 return NULL;
1070 }
1071 if ((na = numaCreate(n)) == NULL)
1072 return (NUMA *)ERROR_PTR("na not made", __func__, NULL);
1073
1074 for (i = 0; i < n; i++) {
1075 if (fscanf(fp, " [%d] = %f\n", &index, &val) != 2) {
1076 numaDestroy(&na);
1077 return (NUMA *)ERROR_PTR("bad input data", __func__, NULL);
1078 }
1079 numaAddNumber(na, val);
1080 }
1081
1082 /* Optional data */
1083 if (fscanf(fp, "startx = %f, delx = %f\n", &startx, &delx) == 2)
1084 numaSetParameters(na, startx, delx);
1085
1086 return na;
1087}
1088
1089
1097NUMA *
1098numaReadMem(const l_uint8 *data,
1099 size_t size)
1100{
1101FILE *fp;
1102NUMA *na;
1103
1104 if (!data)
1105 return (NUMA *)ERROR_PTR("data not defined", __func__, NULL);
1106 if ((fp = fopenReadFromMemory(data, size)) == NULL)
1107 return (NUMA *)ERROR_PTR("stream not opened", __func__, NULL);
1108
1109 na = numaReadStream(fp);
1110 fclose(fp);
1111 if (!na) L_ERROR("numa not read\n", __func__);
1112 return na;
1113}
1114
1115
1132l_ok
1133numaWriteDebug(const char *filename,
1134 NUMA *na)
1135{
1136 if (LeptDebugOK) {
1137 return numaWrite(filename, na);
1138 } else {
1139 L_INFO("write to named temp file %s is disabled\n", __func__, filename);
1140 return 0;
1141 }
1142}
1143
1144
1152l_ok
1153numaWrite(const char *filename,
1154 NUMA *na)
1155{
1156l_int32 ret;
1157FILE *fp;
1158
1159 if (!filename)
1160 return ERROR_INT("filename not defined", __func__, 1);
1161 if (!na)
1162 return ERROR_INT("na not defined", __func__, 1);
1163
1164 if ((fp = fopenWriteStream(filename, "w")) == NULL)
1165 return ERROR_INT_1("stream not opened", filename, __func__, 1);
1166 ret = numaWriteStream(fp, na);
1167 fclose(fp);
1168 if (ret)
1169 return ERROR_INT_1("na not written to stream", filename, __func__, 1);
1170 return 0;
1171}
1172
1173
1181l_ok
1183 NUMA *na)
1184{
1185l_int32 i, n;
1186l_float32 startx, delx;
1187
1188 if (!na)
1189 return ERROR_INT("na not defined", __func__, 1);
1190 if (!fp)
1191 return numaWriteStderr(na);
1192
1193 n = numaGetCount(na);
1194 fprintf(fp, "\nNuma Version %d\n", NUMA_VERSION_NUMBER);
1195 fprintf(fp, "Number of numbers = %d\n", n);
1196 for (i = 0; i < n; i++)
1197 fprintf(fp, " [%d] = %f\n", i, na->array[i]);
1198 fprintf(fp, "\n");
1199
1200 /* Optional data */
1201 numaGetParameters(na, &startx, &delx);
1202 if (startx != 0.0 || delx != 1.0)
1203 fprintf(fp, "startx = %f, delx = %f\n", startx, delx);
1204
1205 return 0;
1206}
1207
1208
1215l_ok
1217{
1218l_int32 i, n;
1219l_float32 startx, delx;
1220
1221 if (!na)
1222 return ERROR_INT("na not defined", __func__, 1);
1223
1224 n = numaGetCount(na);
1225 lept_stderr("\nNuma Version %d\n", NUMA_VERSION_NUMBER);
1226 lept_stderr("Number of numbers = %d\n", n);
1227 for (i = 0; i < n; i++)
1228 lept_stderr(" [%d] = %f\n", i, na->array[i]);
1229 lept_stderr("\n");
1230
1231 /* Optional data */
1232 numaGetParameters(na, &startx, &delx);
1233 if (startx != 0.0 || delx != 1.0)
1234 lept_stderr("startx = %f, delx = %f\n", startx, delx);
1235
1236 return 0;
1237}
1238
1239
1253l_ok
1254numaWriteMem(l_uint8 **pdata,
1255 size_t *psize,
1256 NUMA *na)
1257{
1258l_int32 ret;
1259FILE *fp;
1260
1261 if (pdata) *pdata = NULL;
1262 if (psize) *psize = 0;
1263 if (!pdata)
1264 return ERROR_INT("&data not defined", __func__, 1);
1265 if (!psize)
1266 return ERROR_INT("&size not defined", __func__, 1);
1267 if (!na)
1268 return ERROR_INT("na not defined", __func__, 1);
1269
1270#if HAVE_FMEMOPEN
1271 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1272 return ERROR_INT("stream not opened", __func__, 1);
1273 ret = numaWriteStream(fp, na);
1274 fputc('\0', fp);
1275 fclose(fp);
1276 if (*psize > 0) *psize = *psize - 1;
1277#else
1278 L_INFO("no fmemopen API --> work-around: write to temp file\n", __func__);
1279 #ifdef _WIN32
1280 if ((fp = fopenWriteWinTempfile()) == NULL)
1281 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1282 #else
1283 if ((fp = tmpfile()) == NULL)
1284 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1285 #endif /* _WIN32 */
1286 ret = numaWriteStream(fp, na);
1287 rewind(fp);
1288 *pdata = l_binaryReadStream(fp, psize);
1289 fclose(fp);
1290#endif /* HAVE_FMEMOPEN */
1291 return ret;
1292}
1293
1294
1295/*--------------------------------------------------------------------------*
1296 * Numaa creation, destruction *
1297 *--------------------------------------------------------------------------*/
1305NUMAA *
1306numaaCreate(l_int32 n)
1307{
1308NUMAA *naa;
1309
1310 if (n <= 0 || n > MaxPtrArraySize)
1311 n = InitialArraySize;
1312
1313 naa = (NUMAA *)LEPT_CALLOC(1, sizeof(NUMAA));
1314 if ((naa->numa = (NUMA **)LEPT_CALLOC(n, sizeof(NUMA *))) == NULL) {
1315 numaaDestroy(&naa);
1316 return (NUMAA *)ERROR_PTR("numa ptr array not made", __func__, NULL);
1317 }
1318
1319 naa->nalloc = n;
1320 naa->n = 0;
1321 return naa;
1322}
1323
1324
1341NUMAA *
1342numaaCreateFull(l_int32 nptr,
1343 l_int32 n)
1344{
1345l_int32 i;
1346NUMAA *naa;
1347NUMA *na;
1348
1349 naa = numaaCreate(nptr);
1350 for (i = 0; i < nptr; i++) {
1351 na = numaCreate(n);
1352 numaaAddNuma(naa, na, L_INSERT);
1353 }
1354
1355 return naa;
1356}
1357
1358
1372l_ok
1374{
1375l_int32 i, n, nn;
1376NUMA *na;
1377
1378 if (!naa)
1379 return ERROR_INT("naa not defined", __func__, 1);
1380
1381 n = numaaGetCount(naa);
1382 for (i = n - 1; i >= 0; i--) {
1383 na = numaaGetNuma(naa, i, L_CLONE);
1384 if (!na)
1385 continue;
1386 nn = numaGetCount(na);
1387 numaDestroy(&na);
1388 if (nn == 0)
1389 numaDestroy(&naa->numa[i]);
1390 else
1391 break;
1392 }
1393 naa->n = i + 1;
1394 return 0;
1395}
1396
1397
1404void
1406{
1407l_int32 i;
1408NUMAA *naa;
1409
1410 if (pnaa == NULL) {
1411 L_WARNING("ptr address is NULL!\n", __func__);
1412 return;
1413 }
1414
1415 if ((naa = *pnaa) == NULL)
1416 return;
1417
1418 for (i = 0; i < naa->n; i++)
1419 numaDestroy(&naa->numa[i]);
1420 LEPT_FREE(naa->numa);
1421 LEPT_FREE(naa);
1422 *pnaa = NULL;
1423}
1424
1425
1426
1427/*--------------------------------------------------------------------------*
1428 * Add Numa to Numaa *
1429 *--------------------------------------------------------------------------*/
1438l_ok
1440 NUMA *na,
1441 l_int32 copyflag)
1442{
1443l_int32 n;
1444NUMA *nac;
1445
1446 if (!naa)
1447 return ERROR_INT("naa not defined", __func__, 1);
1448 if (!na)
1449 return ERROR_INT("na not defined", __func__, 1);
1450
1451 if (copyflag == L_INSERT) {
1452 nac = na;
1453 } else if (copyflag == L_COPY) {
1454 if ((nac = numaCopy(na)) == NULL)
1455 return ERROR_INT("nac not made", __func__, 1);
1456 } else if (copyflag == L_CLONE) {
1457 nac = numaClone(na);
1458 } else {
1459 return ERROR_INT("invalid copyflag", __func__, 1);
1460 }
1461
1462 n = numaaGetCount(naa);
1463 if (n >= naa->nalloc) {
1464 if (numaaExtendArray(naa)) {
1465 if (copyflag != L_INSERT)
1466 numaDestroy(&nac);
1467 return ERROR_INT("extension failed", __func__, 1);
1468 }
1469 }
1470 naa->numa[n] = nac;
1471 naa->n++;
1472 return 0;
1473}
1474
1475
1487static l_int32
1489{
1490size_t oldsize, newsize;
1491
1492 if (!naa)
1493 return ERROR_INT("naa not defined", __func__, 1);
1494 if (naa->nalloc > MaxPtrArraySize) /* belt & suspenders */
1495 return ERROR_INT("naa has too many ptrs", __func__, 1);
1496 oldsize = naa->nalloc * sizeof(NUMA *);
1497 newsize = 2 * oldsize;
1498 if (newsize > 8 * MaxPtrArraySize)
1499 return ERROR_INT("newsize > 8 MB; too large", __func__, 1);
1500
1501 if ((naa->numa = (NUMA **)reallocNew((void **)&naa->numa,
1502 oldsize, newsize)) == NULL)
1503 return ERROR_INT("new ptr array not returned", __func__, 1);
1504
1505 naa->nalloc *= 2;
1506 return 0;
1507}
1508
1509
1510/*----------------------------------------------------------------------*
1511 * Numaa accessors *
1512 *----------------------------------------------------------------------*/
1519l_int32
1521{
1522 if (!naa)
1523 return ERROR_INT("naa not defined", __func__, 0);
1524 return naa->n;
1525}
1526
1527
1535l_int32
1537 l_int32 index)
1538{
1539 if (!naa)
1540 return ERROR_INT("naa not defined", __func__, 0);
1541 if (index < 0 || index >= naa->n)
1542 return ERROR_INT("invalid index into naa", __func__, 0);
1543 return numaGetCount(naa->numa[index]);
1544}
1545
1546
1554l_int32
1556{
1557NUMA *na;
1558l_int32 n, sum, i;
1559
1560 if (!naa)
1561 return ERROR_INT("naa not defined", __func__, 0);
1562
1563 n = numaaGetCount(naa);
1564 for (sum = 0, i = 0; i < n; i++) {
1565 na = numaaGetNuma(naa, i, L_CLONE);
1566 sum += numaGetCount(na);
1567 numaDestroy(&na);
1568 }
1569
1570 return sum;
1571}
1572
1573
1601NUMA **
1603{
1604 if (!naa)
1605 return (NUMA **)ERROR_PTR("naa not defined", __func__, NULL);
1606
1607 naa->n = naa->nalloc;
1608 return naa->numa;
1609}
1610
1611
1620NUMA *
1622 l_int32 index,
1623 l_int32 accessflag)
1624{
1625 if (!naa)
1626 return (NUMA *)ERROR_PTR("naa not defined", __func__, NULL);
1627 if (index < 0 || index >= naa->n)
1628 return (NUMA *)ERROR_PTR("index not valid", __func__, NULL);
1629
1630 if (accessflag == L_COPY)
1631 return numaCopy(naa->numa[index]);
1632 else if (accessflag == L_CLONE)
1633 return numaClone(naa->numa[index]);
1634 else
1635 return (NUMA *)ERROR_PTR("invalid accessflag", __func__, NULL);
1636}
1637
1638
1654l_ok
1656 l_int32 index,
1657 NUMA *na)
1658{
1659l_int32 n;
1660
1661 if (!naa)
1662 return ERROR_INT("naa not defined", __func__, 1);
1663 if (!na)
1664 return ERROR_INT("na not defined", __func__, 1);
1665 n = numaaGetCount(naa);
1666 if (index < 0 || index >= n)
1667 return ERROR_INT("index not valid", __func__, 1);
1668
1669 numaDestroy(&naa->numa[index]);
1670 naa->numa[index] = na;
1671 return 0;
1672}
1673
1674
1685l_ok
1687 l_int32 i,
1688 l_int32 j,
1689 l_float32 *pfval,
1690 l_int32 *pival)
1691{
1692l_int32 n;
1693NUMA *na;
1694
1695 if (!pfval && !pival)
1696 return ERROR_INT("no return val requested", __func__, 1);
1697 if (pfval) *pfval = 0.0;
1698 if (pival) *pival = 0;
1699 if (!naa)
1700 return ERROR_INT("naa not defined", __func__, 1);
1701 n = numaaGetCount(naa);
1702 if (i < 0 || i >= n)
1703 return ERROR_INT("invalid index into naa", __func__, 1);
1704 na = naa->numa[i];
1705 if (j < 0 || j >= na->n)
1706 return ERROR_INT("invalid index into na", __func__, 1);
1707 if (pfval) *pfval = na->array[j];
1708 if (pival) *pival = (l_int32)(na->array[j]);
1709 return 0;
1710}
1711
1712
1726l_ok
1728 l_int32 index,
1729 l_float32 val)
1730{
1731l_int32 n;
1732NUMA *na;
1733
1734 if (!naa)
1735 return ERROR_INT("naa not defined", __func__, 1);
1736 n = numaaGetCount(naa);
1737 if (index < 0 || index >= n)
1738 return ERROR_INT("invalid index in naa", __func__, 1);
1739
1740 na = numaaGetNuma(naa, index, L_CLONE);
1741 numaAddNumber(na, val);
1742 numaDestroy(&na);
1743 return 0;
1744}
1745
1746
1747/*----------------------------------------------------------------------*
1748 * Serialize numaa for I/O *
1749 *----------------------------------------------------------------------*/
1756NUMAA *
1757numaaRead(const char *filename)
1758{
1759FILE *fp;
1760NUMAA *naa;
1761
1762 if (!filename)
1763 return (NUMAA *)ERROR_PTR("filename not defined", __func__, NULL);
1764
1765 if ((fp = fopenReadStream(filename)) == NULL)
1766 return (NUMAA *)ERROR_PTR_1("stream not opened",
1767 filename, __func__, NULL);
1768 naa = numaaReadStream(fp);
1769 fclose(fp);
1770 if (!naa)
1771 return (NUMAA *)ERROR_PTR_1("naa not read",
1772 filename, __func__, NULL);
1773 return naa;
1774}
1775
1776
1783NUMAA *
1785{
1786l_int32 i, n, index, ret, version;
1787NUMA *na;
1788NUMAA *naa;
1789
1790 if (!fp)
1791 return (NUMAA *)ERROR_PTR("stream not defined", __func__, NULL);
1792
1793 ret = fscanf(fp, "\nNumaa Version %d\n", &version);
1794 if (ret != 1)
1795 return (NUMAA *)ERROR_PTR("not a numa file", __func__, NULL);
1796 if (version != NUMA_VERSION_NUMBER)
1797 return (NUMAA *)ERROR_PTR("invalid numaa version", __func__, NULL);
1798 if (fscanf(fp, "Number of numa = %d\n\n", &n) != 1)
1799 return (NUMAA *)ERROR_PTR("invalid number of numa", __func__, NULL);
1800
1801 if (n > MaxPtrArraySize) {
1802 L_ERROR("n = %d > %d\n", __func__, n, MaxPtrArraySize);
1803 return NULL;
1804 }
1805 if ((naa = numaaCreate(n)) == NULL)
1806 return (NUMAA *)ERROR_PTR("naa not made", __func__, NULL);
1807
1808 for (i = 0; i < n; i++) {
1809 if (fscanf(fp, "Numa[%d]:", &index) != 1) {
1810 numaaDestroy(&naa);
1811 return (NUMAA *)ERROR_PTR("invalid numa header", __func__, NULL);
1812 }
1813 if ((na = numaReadStream(fp)) == NULL) {
1814 numaaDestroy(&naa);
1815 return (NUMAA *)ERROR_PTR("na not made", __func__, NULL);
1816 }
1817 numaaAddNuma(naa, na, L_INSERT);
1818 }
1819
1820 return naa;
1821}
1822
1823
1831NUMAA *
1832numaaReadMem(const l_uint8 *data,
1833 size_t size)
1834{
1835FILE *fp;
1836NUMAA *naa;
1837
1838 if (!data)
1839 return (NUMAA *)ERROR_PTR("data not defined", __func__, NULL);
1840 if ((fp = fopenReadFromMemory(data, size)) == NULL)
1841 return (NUMAA *)ERROR_PTR("stream not opened", __func__, NULL);
1842
1843 naa = numaaReadStream(fp);
1844 fclose(fp);
1845 if (!naa) L_ERROR("naa not read\n", __func__);
1846 return naa;
1847}
1848
1849
1857l_ok
1858numaaWrite(const char *filename,
1859 NUMAA *naa)
1860{
1861l_int32 ret;
1862FILE *fp;
1863
1864 if (!filename)
1865 return ERROR_INT("filename not defined", __func__, 1);
1866 if (!naa)
1867 return ERROR_INT("naa not defined", __func__, 1);
1868
1869 if ((fp = fopenWriteStream(filename, "w")) == NULL)
1870 return ERROR_INT_1("stream not opened", filename, __func__, 1);
1871 ret = numaaWriteStream(fp, naa);
1872 fclose(fp);
1873 if (ret)
1874 return ERROR_INT_1("naa not written to stream", filename, __func__, 1);
1875 return 0;
1876}
1877
1878
1886l_ok
1888 NUMAA *naa)
1889{
1890l_int32 i, n;
1891NUMA *na;
1892
1893 if (!fp)
1894 return ERROR_INT("stream not defined", __func__, 1);
1895 if (!naa)
1896 return ERROR_INT("naa not defined", __func__, 1);
1897
1898 n = numaaGetCount(naa);
1899 fprintf(fp, "\nNumaa Version %d\n", NUMA_VERSION_NUMBER);
1900 fprintf(fp, "Number of numa = %d\n\n", n);
1901 for (i = 0; i < n; i++) {
1902 if ((na = numaaGetNuma(naa, i, L_CLONE)) == NULL)
1903 return ERROR_INT("na not found", __func__, 1);
1904 fprintf(fp, "Numa[%d]:", i);
1905 numaWriteStream(fp, na);
1906 numaDestroy(&na);
1907 }
1908
1909 return 0;
1910}
1911
1912
1926l_ok
1927numaaWriteMem(l_uint8 **pdata,
1928 size_t *psize,
1929 NUMAA *naa)
1930{
1931l_int32 ret;
1932FILE *fp;
1933
1934 if (pdata) *pdata = NULL;
1935 if (psize) *psize = 0;
1936 if (!pdata)
1937 return ERROR_INT("&data not defined", __func__, 1);
1938 if (!psize)
1939 return ERROR_INT("&size not defined", __func__, 1);
1940 if (!naa)
1941 return ERROR_INT("naa not defined", __func__, 1);
1942
1943#if HAVE_FMEMOPEN
1944 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1945 return ERROR_INT("stream not opened", __func__, 1);
1946 ret = numaaWriteStream(fp, naa);
1947 fputc('\0', fp);
1948 fclose(fp);
1949 if (*psize > 0) *psize = *psize - 1;
1950#else
1951 L_INFO("no fmemopen API --> work-around: write to temp file\n", __func__);
1952 #ifdef _WIN32
1953 if ((fp = fopenWriteWinTempfile()) == NULL)
1954 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1955 #else
1956 if ((fp = tmpfile()) == NULL)
1957 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1958 #endif /* _WIN32 */
1959 ret = numaaWriteStream(fp, naa);
1960 rewind(fp);
1961 *pdata = l_binaryReadStream(fp, psize);
1962 fclose(fp);
1963#endif /* HAVE_FMEMOPEN */
1964 return ret;
1965}
1966
@ L_FLOAT_VALUE
Definition array.h:106
@ L_INTEGER_VALUE
Definition array.h:105
#define NUMA_VERSION_NUMBER
l_ok numaaWriteMem(l_uint8 **pdata, size_t *psize, NUMAA *naa)
numaaWriteMem()
Definition numabasic.c:1927
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition numabasic.c:460
l_int32 numaaGetNumberCount(NUMAA *naa)
numaaGetNumberCount()
Definition numabasic.c:1555
NUMA * numaCopy(NUMA *na)
numaCopy()
Definition numabasic.c:387
l_ok numaReplaceNumber(NUMA *na, l_int32 index, l_float32 val)
numaReplaceNumber()
Definition numabasic.c:601
l_ok numaGetFValue(NUMA *na, l_int32 index, l_float32 *pval)
numaGetFValue()
Definition numabasic.c:687
SARRAY * numaConvertToSarray(NUMA *na, l_int32 size1, l_int32 size2, l_int32 addzeros, l_int32 type)
numaConvertToSarray()
Definition numabasic.c:969
l_ok numaWriteStderr(NUMA *na)
numaWriteStderr()
Definition numabasic.c:1216
NUMA * numaaGetNuma(NUMAA *naa, l_int32 index, l_int32 accessflag)
numaaGetNuma()
Definition numabasic.c:1621
l_ok numaWrite(const char *filename, NUMA *na)
numaWrite()
Definition numabasic.c:1153
l_int32 numaaGetCount(NUMAA *naa)
numaaGetCount()
Definition numabasic.c:1520
l_int32 * numaGetIArray(NUMA *na)
numaGetIArray()
Definition numabasic.c:807
l_ok numaaAddNumber(NUMAA *naa, l_int32 index, l_float32 val)
numaaAddNumber()
Definition numabasic.c:1727
l_ok numaInsertNumber(NUMA *na, l_int32 index, l_float32 val)
numaInsertNumber()
Definition numabasic.c:531
l_ok numaaWriteStream(FILE *fp, NUMAA *naa)
numaaWriteStream()
Definition numabasic.c:1887
l_int32 numaaGetNumaCount(NUMAA *naa, l_int32 index)
numaaGetNumaCount()
Definition numabasic.c:1536
l_ok numaSetCount(NUMA *na, l_int32 newcount)
numaSetCount()
Definition numabasic.c:655
l_ok numaaGetValue(NUMAA *naa, l_int32 i, l_int32 j, l_float32 *pfval, l_int32 *pival)
numaaGetValue()
Definition numabasic.c:1686
void numaDestroy(NUMA **pna)
numaDestroy()
Definition numabasic.c:357
NUMA ** numaaGetPtrArray(NUMAA *naa)
numaaGetPtrArray()
Definition numabasic.c:1602
l_ok numaaTruncate(NUMAA *naa)
numaaTruncate()
Definition numabasic.c:1373
NUMAA * numaaCreateFull(l_int32 nptr, l_int32 n)
numaaCreateFull()
Definition numabasic.c:1342
l_ok numaSetValue(NUMA *na, l_int32 index, l_float32 val)
numaSetValue()
Definition numabasic.c:750
l_float32 * numaGetFArray(NUMA *na, l_int32 copyflag)
numaGetFArray()
Definition numabasic.c:851
l_ok numaEmpty(NUMA *na)
numaEmpty()
Definition numabasic.c:438
NUMA * numaReadMem(const l_uint8 *data, size_t size)
numaReadMem()
Definition numabasic.c:1098
l_int32 numaGetCount(NUMA *na)
numaGetCount()
Definition numabasic.c:630
l_ok numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition numabasic.c:720
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition numabasic.c:193
l_ok numaRemoveNumber(NUMA *na, l_int32 index)
numaRemoveNumber()
Definition numabasic.c:572
l_ok numaaAddNuma(NUMAA *naa, NUMA *na, l_int32 copyflag)
numaaAddNuma()
Definition numabasic.c:1439
l_ok numaaWrite(const char *filename, NUMAA *naa)
numaaWrite()
Definition numabasic.c:1858
NUMA * numaCreateFromString(const char *str)
numaCreateFromString()
Definition numabasic.c:308
l_ok numaWriteDebug(const char *filename, NUMA *na)
numaWriteDebug()
Definition numabasic.c:1133
static const l_int32 InitialArraySize
Definition numabasic.c:177
l_ok numaShiftValue(NUMA *na, l_int32 index, l_float32 diff)
numaShiftValue()
Definition numabasic.c:773
static l_int32 numaExtendArray(NUMA *na)
numaExtendArray()
Definition numabasic.c:491
l_ok numaWriteMem(l_uint8 **pdata, size_t *psize, NUMA *na)
numaWriteMem()
Definition numabasic.c:1254
NUMA * numaReadStream(FILE *fp)
numaReadStream()
Definition numabasic.c:1050
NUMAA * numaaRead(const char *filename)
numaaRead()
Definition numabasic.c:1757
l_ok numaGetParameters(NUMA *na, l_float32 *pstartx, l_float32 *pdelx)
numaGetParameters()
Definition numabasic.c:884
NUMA * numaCreateFromIArray(l_int32 *iarray, l_int32 size)
numaCreateFromIArray()
Definition numabasic.c:231
NUMA * numaClone(NUMA *na)
numaClone()
Definition numabasic.c:414
NUMA * numaCreateFromFArray(l_float32 *farray, l_int32 size, l_int32 copyflag)
numaCreateFromFArray()
Definition numabasic.c:266
NUMA * numaRead(const char *filename)
numaRead()
Definition numabasic.c:1023
NUMAA * numaaCreate(l_int32 n)
numaaCreate()
Definition numabasic.c:1306
void numaaDestroy(NUMAA **pnaa)
numaaDestroy()
Definition numabasic.c:1405
NUMAA * numaaReadStream(FILE *fp)
numaaReadStream()
Definition numabasic.c:1784
NUMAA * numaaReadMem(const l_uint8 *data, size_t size)
numaaReadMem()
Definition numabasic.c:1832
l_ok numaCopyParameters(NUMA *nad, NUMA *nas)
numaCopyParameters()
Definition numabasic.c:933
l_ok numaSetParameters(NUMA *na, l_float32 startx, l_float32 delx)
numaSetParameters()
Definition numabasic.c:912
l_ok numaaReplaceNuma(NUMAA *naa, l_int32 index, NUMA *na)
numaaReplaceNuma()
Definition numabasic.c:1655
l_ok numaWriteStream(FILE *fp, NUMA *na)
numaWriteStream()
Definition numabasic.c:1182
static l_int32 numaaExtendArray(NUMAA *naa)
numaaExtendArray()
Definition numabasic.c:1488
@ L_COPY
Definition pix.h:505
@ L_CLONE
Definition pix.h:506
@ L_NOCOPY
Definition pix.h:503
@ L_INSERT
Definition pix.h:504
l_float32 startx
l_float32 delx
l_int32 nalloc
l_float32 * array
l_int32 n
l_atomic refcount
struct Numa ** numa
l_int32 n
l_int32 nalloc