Leptonica 1.83.1
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
164
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;
178
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 n = numaGetCount(na);
816 if ((array = (l_int32 *)LEPT_CALLOC(n, sizeof(l_int32))) == NULL)
817 return (l_int32 *)ERROR_PTR("array not made", __func__, NULL);
818 for (i = 0; i < n; i++) {
819 numaGetIValue(na, i, &ival);
820 array[i] = ival;
821 }
822
823 return array;
824}
825
826
849l_float32 *
851 l_int32 copyflag)
852{
853l_int32 i, n;
854l_float32 *array;
855
856 if (!na)
857 return (l_float32 *)ERROR_PTR("na not defined", __func__, NULL);
858
859 if (copyflag == L_NOCOPY) {
860 array = na->array;
861 } else { /* copyflag == L_COPY */
862 n = numaGetCount(na);
863 if ((array = (l_float32 *)LEPT_CALLOC(n, sizeof(l_float32))) == NULL)
864 return (l_float32 *)ERROR_PTR("array not made", __func__, NULL);
865 for (i = 0; i < n; i++)
866 array[i] = na->array[i];
867 }
868
869 return array;
870}
871
872
881l_ok
883 l_float32 *pstartx,
884 l_float32 *pdelx)
885{
886 if (!pdelx && !pstartx)
887 return ERROR_INT("no return val requested", __func__, 1);
888 if (pstartx) *pstartx = 0.0;
889 if (pdelx) *pdelx = 1.0;
890 if (!na)
891 return ERROR_INT("na not defined", __func__, 1);
892
893 if (pstartx) *pstartx = na->startx;
894 if (pdelx) *pdelx = na->delx;
895 return 0;
896}
897
898
909l_ok
911 l_float32 startx,
912 l_float32 delx)
913{
914 if (!na)
915 return ERROR_INT("na not defined", __func__, 1);
916
917 na->startx = startx;
918 na->delx = delx;
919 return 0;
920}
921
922
930l_ok
932 NUMA *nas)
933{
934l_float32 start, binsize;
935
936 if (!nas || !nad)
937 return ERROR_INT("nas and nad not both defined", __func__, 1);
938
939 numaGetParameters(nas, &start, &binsize);
940 numaSetParameters(nad, start, binsize);
941 return 0;
942}
943
944
945/*----------------------------------------------------------------------*
946 * Convert to string array *
947 *----------------------------------------------------------------------*/
966SARRAY *
968 l_int32 size1,
969 l_int32 size2,
970 l_int32 addzeros,
971 l_int32 type)
972{
973char fmt[32], strbuf[64];
974l_int32 i, n, ival;
975l_float32 fval;
976SARRAY *sa;
977
978 if (!na)
979 return (SARRAY *)ERROR_PTR("na not defined", __func__, NULL);
980 if (type != L_INTEGER_VALUE && type != L_FLOAT_VALUE)
981 return (SARRAY *)ERROR_PTR("invalid type", __func__, NULL);
982
983 if (type == L_INTEGER_VALUE) {
984 if (addzeros)
985 snprintf(fmt, sizeof(fmt), "%%0%dd", size1);
986 else
987 snprintf(fmt, sizeof(fmt), "%%%dd", size1);
988 } else { /* L_FLOAT_VALUE */
989 snprintf(fmt, sizeof(fmt), "%%%d.%df", size1, size2);
990 }
991
992 n = numaGetCount(na);
993 if ((sa = sarrayCreate(n)) == NULL)
994 return (SARRAY *)ERROR_PTR("sa not made", __func__, NULL);
995
996 for (i = 0; i < n; i++) {
997 if (type == L_INTEGER_VALUE) {
998 numaGetIValue(na, i, &ival);
999 snprintf(strbuf, sizeof(strbuf), fmt, ival);
1000 } else { /* L_FLOAT_VALUE */
1001 numaGetFValue(na, i, &fval);
1002 snprintf(strbuf, sizeof(strbuf), fmt, fval);
1003 }
1004 sarrayAddString(sa, strbuf, L_COPY);
1005 }
1006
1007 return sa;
1008}
1009
1010
1011/*----------------------------------------------------------------------*
1012 * Serialize numa for I/O *
1013 *----------------------------------------------------------------------*/
1020NUMA *
1021numaRead(const char *filename)
1022{
1023FILE *fp;
1024NUMA *na;
1025
1026 if (!filename)
1027 return (NUMA *)ERROR_PTR("filename not defined", __func__, NULL);
1028
1029 if ((fp = fopenReadStream(filename)) == NULL)
1030 return (NUMA *)ERROR_PTR("stream not opened", __func__, NULL);
1031 na = numaReadStream(fp);
1032 fclose(fp);
1033 if (!na)
1034 return (NUMA *)ERROR_PTR("na not read", __func__, NULL);
1035 return na;
1036}
1037
1038
1045NUMA *
1047{
1048l_int32 i, n, index, ret, version;
1049l_float32 val, startx, delx;
1050NUMA *na;
1051
1052 if (!fp)
1053 return (NUMA *)ERROR_PTR("stream not defined", __func__, NULL);
1054
1055 ret = fscanf(fp, "\nNuma Version %d\n", &version);
1056 if (ret != 1)
1057 return (NUMA *)ERROR_PTR("not a numa file", __func__, NULL);
1058 if (version != NUMA_VERSION_NUMBER)
1059 return (NUMA *)ERROR_PTR("invalid numa version", __func__, NULL);
1060 if (fscanf(fp, "Number of numbers = %d\n", &n) != 1)
1061 return (NUMA *)ERROR_PTR("invalid number of numbers", __func__, NULL);
1062
1063 if (n > MaxFloatArraySize) {
1064 L_ERROR("n = %d > %d\n", __func__, n, MaxFloatArraySize);
1065 return NULL;
1066 }
1067 if ((na = numaCreate(n)) == NULL)
1068 return (NUMA *)ERROR_PTR("na not made", __func__, NULL);
1069
1070 for (i = 0; i < n; i++) {
1071 if (fscanf(fp, " [%d] = %f\n", &index, &val) != 2) {
1072 numaDestroy(&na);
1073 return (NUMA *)ERROR_PTR("bad input data", __func__, NULL);
1074 }
1075 numaAddNumber(na, val);
1076 }
1077
1078 /* Optional data */
1079 if (fscanf(fp, "startx = %f, delx = %f\n", &startx, &delx) == 2)
1080 numaSetParameters(na, startx, delx);
1081
1082 return na;
1083}
1084
1085
1093NUMA *
1094numaReadMem(const l_uint8 *data,
1095 size_t size)
1096{
1097FILE *fp;
1098NUMA *na;
1099
1100 if (!data)
1101 return (NUMA *)ERROR_PTR("data not defined", __func__, NULL);
1102 if ((fp = fopenReadFromMemory(data, size)) == NULL)
1103 return (NUMA *)ERROR_PTR("stream not opened", __func__, NULL);
1104
1105 na = numaReadStream(fp);
1106 fclose(fp);
1107 if (!na) L_ERROR("numa not read\n", __func__);
1108 return na;
1109}
1110
1111
1128l_ok
1129numaWriteDebug(const char *filename,
1130 NUMA *na)
1131{
1132 if (LeptDebugOK) {
1133 return numaWrite(filename, na);
1134 } else {
1135 L_INFO("write to named temp file %s is disabled\n", __func__, filename);
1136 return 0;
1137 }
1138}
1139
1140
1148l_ok
1149numaWrite(const char *filename,
1150 NUMA *na)
1151{
1152l_int32 ret;
1153FILE *fp;
1154
1155 if (!filename)
1156 return ERROR_INT("filename not defined", __func__, 1);
1157 if (!na)
1158 return ERROR_INT("na not defined", __func__, 1);
1159
1160 if ((fp = fopenWriteStream(filename, "w")) == NULL)
1161 return ERROR_INT("stream not opened", __func__, 1);
1162 ret = numaWriteStream(fp, na);
1163 fclose(fp);
1164 if (ret)
1165 return ERROR_INT("na not written to stream", __func__, 1);
1166 return 0;
1167}
1168
1169
1177l_ok
1179 NUMA *na)
1180{
1181l_int32 i, n;
1182l_float32 startx, delx;
1183
1184 if (!na)
1185 return ERROR_INT("na not defined", __func__, 1);
1186 if (!fp)
1187 return numaWriteStderr(na);
1188
1189 n = numaGetCount(na);
1190 fprintf(fp, "\nNuma Version %d\n", NUMA_VERSION_NUMBER);
1191 fprintf(fp, "Number of numbers = %d\n", n);
1192 for (i = 0; i < n; i++)
1193 fprintf(fp, " [%d] = %f\n", i, na->array[i]);
1194 fprintf(fp, "\n");
1195
1196 /* Optional data */
1197 numaGetParameters(na, &startx, &delx);
1198 if (startx != 0.0 || delx != 1.0)
1199 fprintf(fp, "startx = %f, delx = %f\n", startx, delx);
1200
1201 return 0;
1202}
1203
1204
1211l_ok
1213{
1214l_int32 i, n;
1215l_float32 startx, delx;
1216
1217 if (!na)
1218 return ERROR_INT("na not defined", __func__, 1);
1219
1220 n = numaGetCount(na);
1221 lept_stderr("\nNuma Version %d\n", NUMA_VERSION_NUMBER);
1222 lept_stderr("Number of numbers = %d\n", n);
1223 for (i = 0; i < n; i++)
1224 lept_stderr(" [%d] = %f\n", i, na->array[i]);
1225 lept_stderr("\n");
1226
1227 /* Optional data */
1228 numaGetParameters(na, &startx, &delx);
1229 if (startx != 0.0 || delx != 1.0)
1230 lept_stderr("startx = %f, delx = %f\n", startx, delx);
1231
1232 return 0;
1233}
1234
1235
1249l_ok
1250numaWriteMem(l_uint8 **pdata,
1251 size_t *psize,
1252 NUMA *na)
1253{
1254l_int32 ret;
1255FILE *fp;
1256
1257 if (pdata) *pdata = NULL;
1258 if (psize) *psize = 0;
1259 if (!pdata)
1260 return ERROR_INT("&data not defined", __func__, 1);
1261 if (!psize)
1262 return ERROR_INT("&size not defined", __func__, 1);
1263 if (!na)
1264 return ERROR_INT("na not defined", __func__, 1);
1265
1266#if HAVE_FMEMOPEN
1267 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1268 return ERROR_INT("stream not opened", __func__, 1);
1269 ret = numaWriteStream(fp, na);
1270 fputc('\0', fp);
1271 fclose(fp);
1272 *psize = *psize - 1;
1273#else
1274 L_INFO("work-around: writing to a temp file\n", __func__);
1275 #ifdef _WIN32
1276 if ((fp = fopenWriteWinTempfile()) == NULL)
1277 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1278 #else
1279 if ((fp = tmpfile()) == NULL)
1280 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1281 #endif /* _WIN32 */
1282 ret = numaWriteStream(fp, na);
1283 rewind(fp);
1284 *pdata = l_binaryReadStream(fp, psize);
1285 fclose(fp);
1286#endif /* HAVE_FMEMOPEN */
1287 return ret;
1288}
1289
1290
1291/*--------------------------------------------------------------------------*
1292 * Numaa creation, destruction *
1293 *--------------------------------------------------------------------------*/
1301NUMAA *
1302numaaCreate(l_int32 n)
1303{
1304NUMAA *naa;
1305
1306 if (n <= 0 || n > MaxPtrArraySize)
1307 n = InitialArraySize;
1308
1309 naa = (NUMAA *)LEPT_CALLOC(1, sizeof(NUMAA));
1310 if ((naa->numa = (NUMA **)LEPT_CALLOC(n, sizeof(NUMA *))) == NULL) {
1311 numaaDestroy(&naa);
1312 return (NUMAA *)ERROR_PTR("numa ptr array not made", __func__, NULL);
1313 }
1314
1315 naa->nalloc = n;
1316 naa->n = 0;
1317 return naa;
1318}
1319
1320
1337NUMAA *
1338numaaCreateFull(l_int32 nptr,
1339 l_int32 n)
1340{
1341l_int32 i;
1342NUMAA *naa;
1343NUMA *na;
1344
1345 naa = numaaCreate(nptr);
1346 for (i = 0; i < nptr; i++) {
1347 na = numaCreate(n);
1348 numaaAddNuma(naa, na, L_INSERT);
1349 }
1350
1351 return naa;
1352}
1353
1354
1368l_ok
1370{
1371l_int32 i, n, nn;
1372NUMA *na;
1373
1374 if (!naa)
1375 return ERROR_INT("naa not defined", __func__, 1);
1376
1377 n = numaaGetCount(naa);
1378 for (i = n - 1; i >= 0; i--) {
1379 na = numaaGetNuma(naa, i, L_CLONE);
1380 if (!na)
1381 continue;
1382 nn = numaGetCount(na);
1383 numaDestroy(&na);
1384 if (nn == 0)
1385 numaDestroy(&naa->numa[i]);
1386 else
1387 break;
1388 }
1389 naa->n = i + 1;
1390 return 0;
1391}
1392
1393
1400void
1402{
1403l_int32 i;
1404NUMAA *naa;
1405
1406 if (pnaa == NULL) {
1407 L_WARNING("ptr address is NULL!\n", __func__);
1408 return;
1409 }
1410
1411 if ((naa = *pnaa) == NULL)
1412 return;
1413
1414 for (i = 0; i < naa->n; i++)
1415 numaDestroy(&naa->numa[i]);
1416 LEPT_FREE(naa->numa);
1417 LEPT_FREE(naa);
1418 *pnaa = NULL;
1419}
1420
1421
1422
1423/*--------------------------------------------------------------------------*
1424 * Add Numa to Numaa *
1425 *--------------------------------------------------------------------------*/
1434l_ok
1436 NUMA *na,
1437 l_int32 copyflag)
1438{
1439l_int32 n;
1440NUMA *nac;
1441
1442 if (!naa)
1443 return ERROR_INT("naa not defined", __func__, 1);
1444 if (!na)
1445 return ERROR_INT("na not defined", __func__, 1);
1446
1447 if (copyflag == L_INSERT) {
1448 nac = na;
1449 } else if (copyflag == L_COPY) {
1450 if ((nac = numaCopy(na)) == NULL)
1451 return ERROR_INT("nac not made", __func__, 1);
1452 } else if (copyflag == L_CLONE) {
1453 nac = numaClone(na);
1454 } else {
1455 return ERROR_INT("invalid copyflag", __func__, 1);
1456 }
1457
1458 n = numaaGetCount(naa);
1459 if (n >= naa->nalloc) {
1460 if (numaaExtendArray(naa)) {
1461 if (copyflag != L_INSERT)
1462 numaDestroy(&nac);
1463 return ERROR_INT("extension failed", __func__, 1);
1464 }
1465 }
1466 naa->numa[n] = nac;
1467 naa->n++;
1468 return 0;
1469}
1470
1471
1483static l_int32
1485{
1486size_t oldsize, newsize;
1487
1488 if (!naa)
1489 return ERROR_INT("naa not defined", __func__, 1);
1490 if (naa->nalloc > MaxPtrArraySize) /* belt & suspenders */
1491 return ERROR_INT("naa has too many ptrs", __func__, 1);
1492 oldsize = naa->nalloc * sizeof(NUMA *);
1493 newsize = 2 * oldsize;
1494 if (newsize > 8 * MaxPtrArraySize)
1495 return ERROR_INT("newsize > 8 MB; too large", __func__, 1);
1496
1497 if ((naa->numa = (NUMA **)reallocNew((void **)&naa->numa,
1498 oldsize, newsize)) == NULL)
1499 return ERROR_INT("new ptr array not returned", __func__, 1);
1500
1501 naa->nalloc *= 2;
1502 return 0;
1503}
1504
1505
1506/*----------------------------------------------------------------------*
1507 * Numaa accessors *
1508 *----------------------------------------------------------------------*/
1515l_int32
1517{
1518 if (!naa)
1519 return ERROR_INT("naa not defined", __func__, 0);
1520 return naa->n;
1521}
1522
1523
1531l_int32
1533 l_int32 index)
1534{
1535 if (!naa)
1536 return ERROR_INT("naa not defined", __func__, 0);
1537 if (index < 0 || index >= naa->n)
1538 return ERROR_INT("invalid index into naa", __func__, 0);
1539 return numaGetCount(naa->numa[index]);
1540}
1541
1542
1550l_int32
1552{
1553NUMA *na;
1554l_int32 n, sum, i;
1555
1556 if (!naa)
1557 return ERROR_INT("naa not defined", __func__, 0);
1558
1559 n = numaaGetCount(naa);
1560 for (sum = 0, i = 0; i < n; i++) {
1561 na = numaaGetNuma(naa, i, L_CLONE);
1562 sum += numaGetCount(na);
1563 numaDestroy(&na);
1564 }
1565
1566 return sum;
1567}
1568
1569
1597NUMA **
1599{
1600 if (!naa)
1601 return (NUMA **)ERROR_PTR("naa not defined", __func__, NULL);
1602
1603 naa->n = naa->nalloc;
1604 return naa->numa;
1605}
1606
1607
1616NUMA *
1618 l_int32 index,
1619 l_int32 accessflag)
1620{
1621 if (!naa)
1622 return (NUMA *)ERROR_PTR("naa not defined", __func__, NULL);
1623 if (index < 0 || index >= naa->n)
1624 return (NUMA *)ERROR_PTR("index not valid", __func__, NULL);
1625
1626 if (accessflag == L_COPY)
1627 return numaCopy(naa->numa[index]);
1628 else if (accessflag == L_CLONE)
1629 return numaClone(naa->numa[index]);
1630 else
1631 return (NUMA *)ERROR_PTR("invalid accessflag", __func__, NULL);
1632}
1633
1634
1650l_ok
1652 l_int32 index,
1653 NUMA *na)
1654{
1655l_int32 n;
1656
1657 if (!naa)
1658 return ERROR_INT("naa not defined", __func__, 1);
1659 if (!na)
1660 return ERROR_INT("na not defined", __func__, 1);
1661 n = numaaGetCount(naa);
1662 if (index < 0 || index >= n)
1663 return ERROR_INT("index not valid", __func__, 1);
1664
1665 numaDestroy(&naa->numa[index]);
1666 naa->numa[index] = na;
1667 return 0;
1668}
1669
1670
1681l_ok
1683 l_int32 i,
1684 l_int32 j,
1685 l_float32 *pfval,
1686 l_int32 *pival)
1687{
1688l_int32 n;
1689NUMA *na;
1690
1691 if (!pfval && !pival)
1692 return ERROR_INT("no return val requested", __func__, 1);
1693 if (pfval) *pfval = 0.0;
1694 if (pival) *pival = 0;
1695 if (!naa)
1696 return ERROR_INT("naa not defined", __func__, 1);
1697 n = numaaGetCount(naa);
1698 if (i < 0 || i >= n)
1699 return ERROR_INT("invalid index into naa", __func__, 1);
1700 na = naa->numa[i];
1701 if (j < 0 || j >= na->n)
1702 return ERROR_INT("invalid index into na", __func__, 1);
1703 if (pfval) *pfval = na->array[j];
1704 if (pival) *pival = (l_int32)(na->array[j]);
1705 return 0;
1706}
1707
1708
1722l_ok
1724 l_int32 index,
1725 l_float32 val)
1726{
1727l_int32 n;
1728NUMA *na;
1729
1730 if (!naa)
1731 return ERROR_INT("naa not defined", __func__, 1);
1732 n = numaaGetCount(naa);
1733 if (index < 0 || index >= n)
1734 return ERROR_INT("invalid index in naa", __func__, 1);
1735
1736 na = numaaGetNuma(naa, index, L_CLONE);
1737 numaAddNumber(na, val);
1738 numaDestroy(&na);
1739 return 0;
1740}
1741
1742
1743/*----------------------------------------------------------------------*
1744 * Serialize numaa for I/O *
1745 *----------------------------------------------------------------------*/
1752NUMAA *
1753numaaRead(const char *filename)
1754{
1755FILE *fp;
1756NUMAA *naa;
1757
1758 if (!filename)
1759 return (NUMAA *)ERROR_PTR("filename not defined", __func__, NULL);
1760
1761 if ((fp = fopenReadStream(filename)) == NULL)
1762 return (NUMAA *)ERROR_PTR("stream not opened", __func__, NULL);
1763 naa = numaaReadStream(fp);
1764 fclose(fp);
1765 if (!naa)
1766 return (NUMAA *)ERROR_PTR("naa not read", __func__, NULL);
1767 return naa;
1768}
1769
1770
1777NUMAA *
1779{
1780l_int32 i, n, index, ret, version;
1781NUMA *na;
1782NUMAA *naa;
1783
1784 if (!fp)
1785 return (NUMAA *)ERROR_PTR("stream not defined", __func__, NULL);
1786
1787 ret = fscanf(fp, "\nNumaa Version %d\n", &version);
1788 if (ret != 1)
1789 return (NUMAA *)ERROR_PTR("not a numa file", __func__, NULL);
1790 if (version != NUMA_VERSION_NUMBER)
1791 return (NUMAA *)ERROR_PTR("invalid numaa version", __func__, NULL);
1792 if (fscanf(fp, "Number of numa = %d\n\n", &n) != 1)
1793 return (NUMAA *)ERROR_PTR("invalid number of numa", __func__, NULL);
1794
1795 if (n > MaxPtrArraySize) {
1796 L_ERROR("n = %d > %d\n", __func__, n, MaxPtrArraySize);
1797 return NULL;
1798 }
1799 if ((naa = numaaCreate(n)) == NULL)
1800 return (NUMAA *)ERROR_PTR("naa not made", __func__, NULL);
1801
1802 for (i = 0; i < n; i++) {
1803 if (fscanf(fp, "Numa[%d]:", &index) != 1) {
1804 numaaDestroy(&naa);
1805 return (NUMAA *)ERROR_PTR("invalid numa header", __func__, NULL);
1806 }
1807 if ((na = numaReadStream(fp)) == NULL) {
1808 numaaDestroy(&naa);
1809 return (NUMAA *)ERROR_PTR("na not made", __func__, NULL);
1810 }
1811 numaaAddNuma(naa, na, L_INSERT);
1812 }
1813
1814 return naa;
1815}
1816
1817
1825NUMAA *
1826numaaReadMem(const l_uint8 *data,
1827 size_t size)
1828{
1829FILE *fp;
1830NUMAA *naa;
1831
1832 if (!data)
1833 return (NUMAA *)ERROR_PTR("data not defined", __func__, NULL);
1834 if ((fp = fopenReadFromMemory(data, size)) == NULL)
1835 return (NUMAA *)ERROR_PTR("stream not opened", __func__, NULL);
1836
1837 naa = numaaReadStream(fp);
1838 fclose(fp);
1839 if (!naa) L_ERROR("naa not read\n", __func__);
1840 return naa;
1841}
1842
1843
1851l_ok
1852numaaWrite(const char *filename,
1853 NUMAA *naa)
1854{
1855l_int32 ret;
1856FILE *fp;
1857
1858 if (!filename)
1859 return ERROR_INT("filename not defined", __func__, 1);
1860 if (!naa)
1861 return ERROR_INT("naa not defined", __func__, 1);
1862
1863 if ((fp = fopenWriteStream(filename, "w")) == NULL)
1864 return ERROR_INT("stream not opened", __func__, 1);
1865 ret = numaaWriteStream(fp, naa);
1866 fclose(fp);
1867 if (ret)
1868 return ERROR_INT("naa not written to stream", __func__, 1);
1869 return 0;
1870}
1871
1872
1880l_ok
1882 NUMAA *naa)
1883{
1884l_int32 i, n;
1885NUMA *na;
1886
1887 if (!fp)
1888 return ERROR_INT("stream not defined", __func__, 1);
1889 if (!naa)
1890 return ERROR_INT("naa not defined", __func__, 1);
1891
1892 n = numaaGetCount(naa);
1893 fprintf(fp, "\nNumaa Version %d\n", NUMA_VERSION_NUMBER);
1894 fprintf(fp, "Number of numa = %d\n\n", n);
1895 for (i = 0; i < n; i++) {
1896 if ((na = numaaGetNuma(naa, i, L_CLONE)) == NULL)
1897 return ERROR_INT("na not found", __func__, 1);
1898 fprintf(fp, "Numa[%d]:", i);
1899 numaWriteStream(fp, na);
1900 numaDestroy(&na);
1901 }
1902
1903 return 0;
1904}
1905
1906
1920l_ok
1921numaaWriteMem(l_uint8 **pdata,
1922 size_t *psize,
1923 NUMAA *naa)
1924{
1925l_int32 ret;
1926FILE *fp;
1927
1928 if (pdata) *pdata = NULL;
1929 if (psize) *psize = 0;
1930 if (!pdata)
1931 return ERROR_INT("&data not defined", __func__, 1);
1932 if (!psize)
1933 return ERROR_INT("&size not defined", __func__, 1);
1934 if (!naa)
1935 return ERROR_INT("naa not defined", __func__, 1);
1936
1937#if HAVE_FMEMOPEN
1938 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1939 return ERROR_INT("stream not opened", __func__, 1);
1940 ret = numaaWriteStream(fp, naa);
1941 fputc('\0', fp);
1942 fclose(fp);
1943 *psize = *psize - 1;
1944#else
1945 L_INFO("work-around: writing to a temp file\n", __func__);
1946 #ifdef _WIN32
1947 if ((fp = fopenWriteWinTempfile()) == NULL)
1948 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1949 #else
1950 if ((fp = tmpfile()) == NULL)
1951 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1952 #endif /* _WIN32 */
1953 ret = numaaWriteStream(fp, naa);
1954 rewind(fp);
1955 *pdata = l_binaryReadStream(fp, psize);
1956 fclose(fp);
1957#endif /* HAVE_FMEMOPEN */
1958 return ret;
1959}
1960
struct Numaa NUMAA
Definition array.h:69
@ L_FLOAT_VALUE
Definition array.h:106
@ L_INTEGER_VALUE
Definition array.h:105
struct Numa NUMA
Definition array.h:66
struct Sarray SARRAY
Definition array.h:81
#define NUMA_VERSION_NUMBER
static const l_int32 InitialArraySize
Definition bbuffer.c:109
l_ok numaaWriteMem(l_uint8 **pdata, size_t *psize, NUMAA *naa)
numaaWriteMem()
Definition numabasic.c:1921
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition numabasic.c:460
l_int32 numaaGetNumberCount(NUMAA *naa)
numaaGetNumberCount()
Definition numabasic.c:1551
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:967
l_ok numaWriteStderr(NUMA *na)
numaWriteStderr()
Definition numabasic.c:1212
NUMA * numaaGetNuma(NUMAA *naa, l_int32 index, l_int32 accessflag)
numaaGetNuma()
Definition numabasic.c:1617
l_ok numaWrite(const char *filename, NUMA *na)
numaWrite()
Definition numabasic.c:1149
l_int32 numaaGetCount(NUMAA *naa)
numaaGetCount()
Definition numabasic.c:1516
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:1723
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:1881
l_int32 numaaGetNumaCount(NUMAA *naa, l_int32 index)
numaaGetNumaCount()
Definition numabasic.c:1532
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:1682
void numaDestroy(NUMA **pna)
numaDestroy()
Definition numabasic.c:357
NUMA ** numaaGetPtrArray(NUMAA *naa)
numaaGetPtrArray()
Definition numabasic.c:1598
l_ok numaaTruncate(NUMAA *naa)
numaaTruncate()
Definition numabasic.c:1369
NUMAA * numaaCreateFull(l_int32 nptr, l_int32 n)
numaaCreateFull()
Definition numabasic.c:1338
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:850
l_ok numaEmpty(NUMA *na)
numaEmpty()
Definition numabasic.c:438
NUMA * numaReadMem(const l_uint8 *data, size_t size)
numaReadMem()
Definition numabasic.c:1094
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:1435
l_ok numaaWrite(const char *filename, NUMAA *naa)
numaaWrite()
Definition numabasic.c:1852
NUMA * numaCreateFromString(const char *str)
numaCreateFromString()
Definition numabasic.c:308
l_ok numaWriteDebug(const char *filename, NUMA *na)
numaWriteDebug()
Definition numabasic.c:1129
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:1250
NUMA * numaReadStream(FILE *fp)
numaReadStream()
Definition numabasic.c:1046
NUMAA * numaaRead(const char *filename)
numaaRead()
Definition numabasic.c:1753
l_ok numaGetParameters(NUMA *na, l_float32 *pstartx, l_float32 *pdelx)
numaGetParameters()
Definition numabasic.c:882
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:1021
NUMAA * numaaCreate(l_int32 n)
numaaCreate()
Definition numabasic.c:1302
void numaaDestroy(NUMAA **pnaa)
numaaDestroy()
Definition numabasic.c:1401
NUMAA * numaaReadStream(FILE *fp)
numaaReadStream()
Definition numabasic.c:1778
NUMAA * numaaReadMem(const l_uint8 *data, size_t size)
numaaReadMem()
Definition numabasic.c:1826
l_ok numaCopyParameters(NUMA *nad, NUMA *nas)
numaCopyParameters()
Definition numabasic.c:931
l_ok numaSetParameters(NUMA *na, l_float32 startx, l_float32 delx)
numaSetParameters()
Definition numabasic.c:910
l_ok numaaReplaceNuma(NUMAA *naa, l_int32 index, NUMA *na)
numaaReplaceNuma()
Definition numabasic.c:1651
l_ok numaWriteStream(FILE *fp, NUMA *na)
numaWriteStream()
Definition numabasic.c:1178
static l_int32 numaaExtendArray(NUMAA *naa)
numaaExtendArray()
Definition numabasic.c:1484
@ 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