Leptonica  1.73
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 
165 #include <string.h>
166 #include <math.h>
167 #include "allheaders.h"
168 
169 static const l_int32 INITIAL_PTR_ARRAYSIZE = 50; /* n'importe quoi */
170 
171  /* Static functions */
172 static l_int32 numaExtendArray(NUMA *na);
173 static l_int32 numaaExtendArray(NUMAA *naa);
174 
175 
176 /*--------------------------------------------------------------------------*
177  * Numa creation, destruction, copy, clone, etc. *
178  *--------------------------------------------------------------------------*/
185 NUMA *
186 numaCreate(l_int32 n)
187 {
188 NUMA *na;
189 
190  PROCNAME("numaCreate");
191 
192  if (n <= 0)
193  n = INITIAL_PTR_ARRAYSIZE;
194 
195  if ((na = (NUMA *)LEPT_CALLOC(1, sizeof(NUMA))) == NULL)
196  return (NUMA *)ERROR_PTR("na not made", procName, NULL);
197  if ((na->array = (l_float32 *)LEPT_CALLOC(n, sizeof(l_float32))) == NULL) {
198  numaDestroy(&na);
199  return (NUMA *)ERROR_PTR("number array not made", procName, NULL);
200  }
201 
202  na->nalloc = n;
203  na->n = 0;
204  na->refcount = 1;
205  na->startx = 0.0;
206  na->delx = 1.0;
207  return na;
208 }
209 
210 
226 NUMA *
227 numaCreateFromIArray(l_int32 *iarray,
228  l_int32 size)
229 {
230 l_int32 i;
231 NUMA *na;
232 
233  PROCNAME("numaCreateFromIArray");
234 
235  if (!iarray)
236  return (NUMA *)ERROR_PTR("iarray not defined", procName, NULL);
237  if (size <= 0)
238  return (NUMA *)ERROR_PTR("size must be > 0", procName, NULL);
239 
240  na = numaCreate(size);
241  for (i = 0; i < size; i++)
242  numaAddNumber(na, iarray[i]);
243 
244  return na;
245 }
246 
247 
263 NUMA *
264 numaCreateFromFArray(l_float32 *farray,
265  l_int32 size,
266  l_int32 copyflag)
267 {
268 l_int32 i;
269 NUMA *na;
270 
271  PROCNAME("numaCreateFromFArray");
272 
273  if (!farray)
274  return (NUMA *)ERROR_PTR("farray not defined", procName, NULL);
275  if (size <= 0)
276  return (NUMA *)ERROR_PTR("size must be > 0", procName, NULL);
277  if (copyflag != L_INSERT && copyflag != L_COPY)
278  return (NUMA *)ERROR_PTR("invalid copyflag", procName, 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 
307 NUMA *
308 numaCreateFromString(const char *str)
309 {
310 char *substr;
311 l_int32 i, n, nerrors;
312 l_float32 val;
313 NUMA *na;
314 SARRAY *sa;
315 
316  PROCNAME("numaCreateFromString");
317 
318  if (!str || (strlen(str) == 0))
319  return (NUMA *)ERROR_PTR("str not defined or empty", procName, NULL);
320 
321  sa = sarrayCreate(0);
322  sarraySplitString(sa, str, ",");
323  n = sarrayGetCount(sa);
324  na = numaCreate(n);
325  nerrors = 0;
326  for (i = 0; i < n; i++) {
327  substr = sarrayGetString(sa, i, L_NOCOPY);
328  if (sscanf(substr, "%f", &val) != 1) {
329  L_ERROR("substr %d not float\n", procName, i);
330  nerrors++;
331  } else {
332  numaAddNumber(na, val);
333  }
334  }
335 
336  sarrayDestroy(&sa);
337  if (nerrors > 0) {
338  numaDestroy(&na);
339  return (NUMA *)ERROR_PTR("non-floats in string", procName, NULL);
340  }
341 
342  return na;
343 }
344 
345 
358 void
360 {
361 NUMA *na;
362 
363  PROCNAME("numaDestroy");
364 
365  if (pna == NULL) {
366  L_WARNING("ptr address is NULL\n", procName);
367  return;
368  }
369 
370  if ((na = *pna) == NULL)
371  return;
372 
373  /* Decrement the ref count. If it is 0, destroy the numa. */
374  numaChangeRefcount(na, -1);
375  if (numaGetRefcount(na) <= 0) {
376  if (na->array)
377  LEPT_FREE(na->array);
378  LEPT_FREE(na);
379  }
380 
381  *pna = NULL;
382  return;
383 }
384 
385 
392 NUMA *
394 {
395 l_int32 i;
396 NUMA *cna;
397 
398  PROCNAME("numaCopy");
399 
400  if (!na)
401  return (NUMA *)ERROR_PTR("na not defined", procName, NULL);
402 
403  if ((cna = numaCreate(na->nalloc)) == NULL)
404  return (NUMA *)ERROR_PTR("cna not made", procName, NULL);
405  cna->startx = na->startx;
406  cna->delx = na->delx;
407 
408  for (i = 0; i < na->n; i++)
409  numaAddNumber(cna, na->array[i]);
410 
411  return cna;
412 }
413 
414 
421 NUMA *
423 {
424  PROCNAME("numaClone");
425 
426  if (!na)
427  return (NUMA *)ERROR_PTR("na not defined", procName, NULL);
428 
429  numaChangeRefcount(na, 1);
430  return na;
431 }
432 
433 
447 l_int32
449 {
450  PROCNAME("numaEmpty");
451 
452  if (!na)
453  return ERROR_INT("na not defined", procName, 1);
454 
455  na->n = 0;
456  return 0;
457 }
458 
459 
460 
461 /*--------------------------------------------------------------------------*
462  * Number array: add number and extend array *
463  *--------------------------------------------------------------------------*/
471 l_int32
473  l_float32 val)
474 {
475 l_int32 n;
476 
477  PROCNAME("numaAddNumber");
478 
479  if (!na)
480  return ERROR_INT("na not defined", procName, 1);
481 
482  n = numaGetCount(na);
483  if (n >= na->nalloc)
484  numaExtendArray(na);
485  na->array[n] = val;
486  na->n++;
487  return 0;
488 }
489 
490 
497 static l_int32
499 {
500  PROCNAME("numaExtendArray");
501 
502  if (!na)
503  return ERROR_INT("na not defined", procName, 1);
504 
505  if ((na->array = (l_float32 *)reallocNew((void **)&na->array,
506  sizeof(l_float32) * na->nalloc,
507  2 * sizeof(l_float32) * na->nalloc)) == NULL)
508  return ERROR_INT("new ptr array not returned", procName, 1);
509 
510  na->nalloc *= 2;
511  return 0;
512 }
513 
514 
532 l_int32
534  l_int32 index,
535  l_float32 val)
536 {
537 l_int32 i, n;
538 
539  PROCNAME("numaInsertNumber");
540 
541  if (!na)
542  return ERROR_INT("na not defined", procName, 1);
543  n = numaGetCount(na);
544  if (index < 0 || index > n)
545  return ERROR_INT("index not in {0...n}", procName, 1);
546 
547  if (n >= na->nalloc)
548  numaExtendArray(na);
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 
571 l_int32
573  l_int32 index)
574 {
575 l_int32 i, n;
576 
577  PROCNAME("numaRemoveNumber");
578 
579  if (!na)
580  return ERROR_INT("na not defined", procName, 1);
581  n = numaGetCount(na);
582  if (index < 0 || index >= n)
583  return ERROR_INT("index not in {0...n - 1}", procName, 1);
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 
600 l_int32
602  l_int32 index,
603  l_float32 val)
604 {
605 l_int32 n;
606 
607  PROCNAME("numaReplaceNumber");
608 
609  if (!na)
610  return ERROR_INT("na not defined", procName, 1);
611  n = numaGetCount(na);
612  if (index < 0 || index >= n)
613  return ERROR_INT("index not in {0...n - 1}", procName, 1);
614 
615  na->array[index] = val;
616  return 0;
617 }
618 
619 
620 /*----------------------------------------------------------------------*
621  * Numa accessors *
622  *----------------------------------------------------------------------*/
629 l_int32
631 {
632  PROCNAME("numaGetCount");
633 
634  if (!na)
635  return ERROR_INT("na not defined", procName, 0);
636  return na->n;
637 }
638 
639 
656 l_int32
658  l_int32 newcount)
659 {
660  PROCNAME("numaSetCount");
661 
662  if (!na)
663  return ERROR_INT("na not defined", procName, 1);
664  if (newcount > na->nalloc) {
665  if ((na->array = (l_float32 *)reallocNew((void **)&na->array,
666  sizeof(l_float32) * na->nalloc,
667  sizeof(l_float32) * newcount)) == NULL)
668  return ERROR_INT("new ptr array not returned", procName, 1);
669  na->nalloc = newcount;
670  }
671  na->n = newcount;
672  return 0;
673 }
674 
675 
690 l_int32
692  l_int32 index,
693  l_float32 *pval)
694 {
695  PROCNAME("numaGetFValue");
696 
697  if (!pval)
698  return ERROR_INT("&val not defined", procName, 1);
699  *pval = 0.0;
700  if (!na)
701  return ERROR_INT("na not defined", procName, 1);
702 
703  if (index < 0 || index >= na->n)
704  return ERROR_INT("index not valid", procName, 1);
705 
706  *pval = na->array[index];
707  return 0;
708 }
709 
710 
725 l_int32
727  l_int32 index,
728  l_int32 *pival)
729 {
730 l_float32 val;
731 
732  PROCNAME("numaGetIValue");
733 
734  if (!pival)
735  return ERROR_INT("&ival not defined", procName, 1);
736  *pival = 0;
737  if (!na)
738  return ERROR_INT("na not defined", procName, 1);
739 
740  if (index < 0 || index >= na->n)
741  return ERROR_INT("index not valid", procName, 1);
742 
743  val = na->array[index];
744  *pival = (l_int32)(val + L_SIGN(val) * 0.5);
745  return 0;
746 }
747 
748 
757 l_int32
759  l_int32 index,
760  l_float32 val)
761 {
762  PROCNAME("numaSetValue");
763 
764  if (!na)
765  return ERROR_INT("na not defined", procName, 1);
766  if (index < 0 || index >= na->n)
767  return ERROR_INT("index not valid", procName, 1);
768 
769  na->array[index] = val;
770  return 0;
771 }
772 
773 
782 l_int32
784  l_int32 index,
785  l_float32 diff)
786 {
787  PROCNAME("numaShiftValue");
788 
789  if (!na)
790  return ERROR_INT("na not defined", procName, 1);
791  if (index < 0 || index >= na->n)
792  return ERROR_INT("index not valid", procName, 1);
793 
794  na->array[index] += diff;
795  return 0;
796 }
797 
798 
818 l_int32 *
820 {
821 l_int32 i, n, ival;
822 l_int32 *array;
823 
824  PROCNAME("numaGetIArray");
825 
826  if (!na)
827  return (l_int32 *)ERROR_PTR("na not defined", procName, NULL);
828 
829  n = numaGetCount(na);
830  if ((array = (l_int32 *)LEPT_CALLOC(n, sizeof(l_int32))) == NULL)
831  return (l_int32 *)ERROR_PTR("array not made", procName, NULL);
832  for (i = 0; i < n; i++) {
833  numaGetIValue(na, i, &ival);
834  array[i] = ival;
835  }
836 
837  return array;
838 }
839 
840 
863 l_float32 *
865  l_int32 copyflag)
866 {
867 l_int32 i, n;
868 l_float32 *array;
869 
870  PROCNAME("numaGetFArray");
871 
872  if (!na)
873  return (l_float32 *)ERROR_PTR("na not defined", procName, NULL);
874 
875  if (copyflag == L_NOCOPY) {
876  array = na->array;
877  } else { /* copyflag == L_COPY */
878  n = numaGetCount(na);
879  if ((array = (l_float32 *)LEPT_CALLOC(n, sizeof(l_float32))) == NULL)
880  return (l_float32 *)ERROR_PTR("array not made", procName, NULL);
881  for (i = 0; i < n; i++)
882  array[i] = na->array[i];
883  }
884 
885  return array;
886 }
887 
888 
895 l_int32
897 {
898  PROCNAME("numaGetRefcount");
899 
900  if (!na)
901  return ERROR_INT("na not defined", procName, UNDEF);
902  return na->refcount;
903 }
904 
905 
913 l_int32
915  l_int32 delta)
916 {
917  PROCNAME("numaChangeRefcount");
918 
919  if (!na)
920  return ERROR_INT("na not defined", procName, 1);
921  na->refcount += delta;
922  return 0;
923 }
924 
925 
934 l_int32
936  l_float32 *pstartx,
937  l_float32 *pdelx)
938 {
939  PROCNAME("numaGetParameters");
940 
941  if (!pdelx && !pstartx)
942  return ERROR_INT("no return val requested", procName, 1);
943  if (pstartx) *pstartx = 0.0;
944  if (pdelx) *pdelx = 1.0;
945  if (!na)
946  return ERROR_INT("na not defined", procName, 1);
947 
948  if (pstartx) *pstartx = na->startx;
949  if (pdelx) *pdelx = na->delx;
950  return 0;
951 }
952 
953 
964 l_int32
966  l_float32 startx,
967  l_float32 delx)
968 {
969  PROCNAME("numaSetParameters");
970 
971  if (!na)
972  return ERROR_INT("na not defined", procName, 1);
973 
974  na->startx = startx;
975  na->delx = delx;
976  return 0;
977 }
978 
979 
987 l_int32
989  NUMA *nas)
990 {
991 l_float32 start, binsize;
992 
993  PROCNAME("numaCopyParameters");
994 
995  if (!nas || !nad)
996  return ERROR_INT("nas and nad not both defined", procName, 1);
997 
998  numaGetParameters(nas, &start, &binsize);
999  numaSetParameters(nad, start, binsize);
1000  return 0;
1001 }
1002 
1003 
1004 /*----------------------------------------------------------------------*
1005  * Convert to string array *
1006  *----------------------------------------------------------------------*/
1025 SARRAY *
1027  l_int32 size1,
1028  l_int32 size2,
1029  l_int32 addzeros,
1030  l_int32 type)
1031 {
1032 char fmt[32], strbuf[64];
1033 l_int32 i, n, ival;
1034 l_float32 fval;
1035 SARRAY *sa;
1036 
1037  PROCNAME("numaConvertToSarray");
1038 
1039  if (!na)
1040  return (SARRAY *)ERROR_PTR("na not defined", procName, NULL);
1041  if (type != L_INTEGER_VALUE && type != L_FLOAT_VALUE)
1042  return (SARRAY *)ERROR_PTR("invalid type", procName, NULL);
1043 
1044  if (type == L_INTEGER_VALUE) {
1045  if (addzeros)
1046  snprintf(fmt, sizeof(fmt), "%%0%dd", size1);
1047  else
1048  snprintf(fmt, sizeof(fmt), "%%%dd", size1);
1049  } else { /* L_FLOAT_VALUE */
1050  snprintf(fmt, sizeof(fmt), "%%%d.%df", size1, size2);
1051  }
1052 
1053  n = numaGetCount(na);
1054  if ((sa = sarrayCreate(n)) == NULL)
1055  return (SARRAY *)ERROR_PTR("sa not made", procName, NULL);
1056 
1057  for (i = 0; i < n; i++) {
1058  if (type == L_INTEGER_VALUE) {
1059  numaGetIValue(na, i, &ival);
1060  snprintf(strbuf, sizeof(strbuf), fmt, ival);
1061  } else { /* L_FLOAT_VALUE */
1062  numaGetFValue(na, i, &fval);
1063  snprintf(strbuf, sizeof(strbuf), fmt, fval);
1064  }
1065  sarrayAddString(sa, strbuf, L_COPY);
1066  }
1067 
1068  return sa;
1069 }
1070 
1071 
1072 /*----------------------------------------------------------------------*
1073  * Serialize numa for I/O *
1074  *----------------------------------------------------------------------*/
1081 NUMA *
1082 numaRead(const char *filename)
1083 {
1084 FILE *fp;
1085 NUMA *na;
1086 
1087  PROCNAME("numaRead");
1088 
1089  if (!filename)
1090  return (NUMA *)ERROR_PTR("filename not defined", procName, NULL);
1091 
1092  if ((fp = fopenReadStream(filename)) == NULL)
1093  return (NUMA *)ERROR_PTR("stream not opened", procName, NULL);
1094  na = numaReadStream(fp);
1095  fclose(fp);
1096  if (!na)
1097  return (NUMA *)ERROR_PTR("na not read", procName, NULL);
1098  return na;
1099 }
1100 
1101 
1108 NUMA *
1110 {
1111 l_int32 i, n, index, ret, version;
1112 l_float32 val, startx, delx;
1113 NUMA *na;
1114 
1115  PROCNAME("numaReadStream");
1116 
1117  if (!fp)
1118  return (NUMA *)ERROR_PTR("stream not defined", procName, NULL);
1119 
1120  ret = fscanf(fp, "\nNuma Version %d\n", &version);
1121  if (ret != 1)
1122  return (NUMA *)ERROR_PTR("not a numa file", procName, NULL);
1123  if (version != NUMA_VERSION_NUMBER)
1124  return (NUMA *)ERROR_PTR("invalid numa version", procName, NULL);
1125  if (fscanf(fp, "Number of numbers = %d\n", &n) != 1)
1126  return (NUMA *)ERROR_PTR("invalid number of numbers", procName, NULL);
1127 
1128  if ((na = numaCreate(n)) == NULL)
1129  return (NUMA *)ERROR_PTR("na not made", procName, NULL);
1130 
1131  for (i = 0; i < n; i++) {
1132  if (fscanf(fp, " [%d] = %f\n", &index, &val) != 2) {
1133  numaDestroy(&na);
1134  return (NUMA *)ERROR_PTR("bad input data", procName, NULL);
1135  }
1136  numaAddNumber(na, val);
1137  }
1138 
1139  /* Optional data */
1140  if (fscanf(fp, "startx = %f, delx = %f\n", &startx, &delx) == 2)
1141  numaSetParameters(na, startx, delx);
1142 
1143  return na;
1144 }
1145 
1146 
1154 NUMA *
1155 numaReadMem(const l_uint8 *data,
1156  size_t size)
1157 {
1158 FILE *fp;
1159 NUMA *na;
1160 
1161  PROCNAME("numaReadMem");
1162 
1163  if (!data)
1164  return (NUMA *)ERROR_PTR("data not defined", procName, NULL);
1165  if ((fp = fopenReadFromMemory(data, size)) == NULL)
1166  return (NUMA *)ERROR_PTR("stream not opened", procName, NULL);
1167 
1168  na = numaReadStream(fp);
1169  fclose(fp);
1170  if (!na) L_ERROR("numa not read\n", procName);
1171  return na;
1172 }
1173 
1174 
1181 l_int32
1182 numaWrite(const char *filename,
1183  NUMA *na)
1184 {
1185 l_int32 ret;
1186 FILE *fp;
1187 
1188  PROCNAME("numaWrite");
1189 
1190  if (!filename)
1191  return ERROR_INT("filename not defined", procName, 1);
1192  if (!na)
1193  return ERROR_INT("na not defined", procName, 1);
1194 
1195  if ((fp = fopenWriteStream(filename, "w")) == NULL)
1196  return ERROR_INT("stream not opened", procName, 1);
1197  ret = numaWriteStream(fp, na);
1198  fclose(fp);
1199  if (ret)
1200  return ERROR_INT("na not written to stream", procName, 1);
1201  return 0;
1202 }
1203 
1204 
1212 l_int32
1214  NUMA *na)
1215 {
1216 l_int32 i, n;
1217 l_float32 startx, delx;
1218 
1219  PROCNAME("numaWriteStream");
1220 
1221  if (!fp)
1222  return ERROR_INT("stream not defined", procName, 1);
1223  if (!na)
1224  return ERROR_INT("na not defined", procName, 1);
1225 
1226  n = numaGetCount(na);
1227  fprintf(fp, "\nNuma Version %d\n", NUMA_VERSION_NUMBER);
1228  fprintf(fp, "Number of numbers = %d\n", n);
1229  for (i = 0; i < n; i++)
1230  fprintf(fp, " [%d] = %f\n", i, na->array[i]);
1231  fprintf(fp, "\n");
1232 
1233  /* Optional data */
1234  numaGetParameters(na, &startx, &delx);
1235  if (startx != 0.0 || delx != 1.0)
1236  fprintf(fp, "startx = %f, delx = %f\n", startx, delx);
1237 
1238  return 0;
1239 }
1240 
1241 
1255 l_int32
1256 numaWriteMem(l_uint8 **pdata,
1257  size_t *psize,
1258  NUMA *na)
1259 {
1260 l_int32 ret;
1261 FILE *fp;
1262 
1263  PROCNAME("numaWriteMem");
1264 
1265  if (pdata) *pdata = NULL;
1266  if (psize) *psize = 0;
1267  if (!pdata)
1268  return ERROR_INT("&data not defined", procName, 1);
1269  if (!psize)
1270  return ERROR_INT("&size not defined", procName, 1);
1271  if (!na)
1272  return ERROR_INT("na not defined", procName, 1);
1273 
1274 #if HAVE_FMEMOPEN
1275  if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1276  return ERROR_INT("stream not opened", procName, 1);
1277  ret = numaWriteStream(fp, na);
1278 #else
1279  L_INFO("work-around: writing to a temp file\n", procName);
1280  #ifdef _WIN32
1281  if ((fp = fopenWriteWinTempfile()) == NULL)
1282  return ERROR_INT("tmpfile stream not opened", procName, 1);
1283  #else
1284  if ((fp = tmpfile()) == NULL)
1285  return ERROR_INT("tmpfile stream not opened", procName, 1);
1286  #endif /* _WIN32 */
1287  ret = numaWriteStream(fp, na);
1288  rewind(fp);
1289  *pdata = l_binaryReadStream(fp, psize);
1290 #endif /* HAVE_FMEMOPEN */
1291  fclose(fp);
1292  return ret;
1293 }
1294 
1295 
1296 /*--------------------------------------------------------------------------*
1297  * Numaa creation, destruction *
1298  *--------------------------------------------------------------------------*/
1306 NUMAA *
1307 numaaCreate(l_int32 n)
1308 {
1309 NUMAA *naa;
1310 
1311  PROCNAME("numaaCreate");
1312 
1313  if (n <= 0)
1314  n = INITIAL_PTR_ARRAYSIZE;
1315 
1316  if ((naa = (NUMAA *)LEPT_CALLOC(1, sizeof(NUMAA))) == NULL)
1317  return (NUMAA *)ERROR_PTR("naa not made", procName, NULL);
1318  if ((naa->numa = (NUMA **)LEPT_CALLOC(n, sizeof(NUMA *))) == NULL) {
1319  numaaDestroy(&naa);
1320  return (NUMAA *)ERROR_PTR("numa ptr array not made", procName, NULL);
1321  }
1322 
1323  naa->nalloc = n;
1324  naa->n = 0;
1325  return naa;
1326 }
1327 
1328 
1344 NUMAA *
1345 numaaCreateFull(l_int32 nptr,
1346  l_int32 n)
1347 {
1348 l_int32 i;
1349 NUMAA *naa;
1350 NUMA *na;
1351 
1352  naa = numaaCreate(nptr);
1353  for (i = 0; i < nptr; i++) {
1354  na = numaCreate(n);
1355  numaaAddNuma(naa, na, L_INSERT);
1356  }
1357 
1358  return naa;
1359 }
1360 
1361 
1375 l_int32
1377 {
1378 l_int32 i, n, nn;
1379 NUMA *na;
1380 
1381  PROCNAME("numaaTruncate");
1382 
1383  if (!naa)
1384  return ERROR_INT("naa not defined", procName, 1);
1385 
1386  n = numaaGetCount(naa);
1387  for (i = n - 1; i >= 0; i--) {
1388  na = numaaGetNuma(naa, i, L_CLONE);
1389  if (!na)
1390  continue;
1391  nn = numaGetCount(na);
1392  numaDestroy(&na);
1393  if (nn == 0)
1394  numaDestroy(&naa->numa[i]);
1395  else
1396  break;
1397  }
1398  naa->n = i + 1;
1399  return 0;
1400 }
1401 
1402 
1409 void
1411 {
1412 l_int32 i;
1413 NUMAA *naa;
1414 
1415  PROCNAME("numaaDestroy");
1416 
1417  if (pnaa == NULL) {
1418  L_WARNING("ptr address is NULL!\n", procName);
1419  return;
1420  }
1421 
1422  if ((naa = *pnaa) == NULL)
1423  return;
1424 
1425  for (i = 0; i < naa->n; i++)
1426  numaDestroy(&naa->numa[i]);
1427  LEPT_FREE(naa->numa);
1428  LEPT_FREE(naa);
1429  *pnaa = NULL;
1430 
1431  return;
1432 }
1433 
1434 
1435 
1436 /*--------------------------------------------------------------------------*
1437  * Add Numa to Numaa *
1438  *--------------------------------------------------------------------------*/
1447 l_int32
1449  NUMA *na,
1450  l_int32 copyflag)
1451 {
1452 l_int32 n;
1453 NUMA *nac;
1454 
1455  PROCNAME("numaaAddNuma");
1456 
1457  if (!naa)
1458  return ERROR_INT("naa not defined", procName, 1);
1459  if (!na)
1460  return ERROR_INT("na not defined", procName, 1);
1461 
1462  if (copyflag == L_INSERT) {
1463  nac = na;
1464  } else if (copyflag == L_COPY) {
1465  if ((nac = numaCopy(na)) == NULL)
1466  return ERROR_INT("nac not made", procName, 1);
1467  } else if (copyflag == L_CLONE) {
1468  nac = numaClone(na);
1469  } else {
1470  return ERROR_INT("invalid copyflag", procName, 1);
1471  }
1472 
1473  n = numaaGetCount(naa);
1474  if (n >= naa->nalloc)
1475  numaaExtendArray(naa);
1476  naa->numa[n] = nac;
1477  naa->n++;
1478  return 0;
1479 }
1480 
1481 
1488 static l_int32
1490 {
1491  PROCNAME("numaaExtendArray");
1492 
1493  if (!naa)
1494  return ERROR_INT("naa not defined", procName, 1);
1495 
1496  if ((naa->numa = (NUMA **)reallocNew((void **)&naa->numa,
1497  sizeof(NUMA *) * naa->nalloc,
1498  2 * sizeof(NUMA *) * naa->nalloc)) == NULL)
1499  return ERROR_INT("new ptr array not returned", procName, 1);
1500 
1501  naa->nalloc *= 2;
1502  return 0;
1503 }
1504 
1505 
1506 /*----------------------------------------------------------------------*
1507  * Numaa accessors *
1508  *----------------------------------------------------------------------*/
1515 l_int32
1517 {
1518  PROCNAME("numaaGetCount");
1519 
1520  if (!naa)
1521  return ERROR_INT("naa not defined", procName, 0);
1522  return naa->n;
1523 }
1524 
1525 
1533 l_int32
1535  l_int32 index)
1536 {
1537  PROCNAME("numaaGetNumaCount");
1538 
1539  if (!naa)
1540  return ERROR_INT("naa not defined", procName, 0);
1541  if (index < 0 || index >= naa->n)
1542  return ERROR_INT("invalid index into naa", procName, 0);
1543  return numaGetCount(naa->numa[index]);
1544 }
1545 
1546 
1554 l_int32
1556 {
1557 NUMA *na;
1558 l_int32 n, sum, i;
1559 
1560  PROCNAME("numaaGetNumberCount");
1561 
1562  if (!naa)
1563  return ERROR_INT("naa not defined", procName, 0);
1564 
1565  n = numaaGetCount(naa);
1566  for (sum = 0, i = 0; i < n; i++) {
1567  na = numaaGetNuma(naa, i, L_CLONE);
1568  sum += numaGetCount(na);
1569  numaDestroy(&na);
1570  }
1571 
1572  return sum;
1573 }
1574 
1575 
1603 NUMA **
1605 {
1606  PROCNAME("numaaGetPtrArray");
1607 
1608  if (!naa)
1609  return (NUMA **)ERROR_PTR("naa not defined", procName, NULL);
1610 
1611  naa->n = naa->nalloc;
1612  return naa->numa;
1613 }
1614 
1615 
1624 NUMA *
1626  l_int32 index,
1627  l_int32 accessflag)
1628 {
1629  PROCNAME("numaaGetNuma");
1630 
1631  if (!naa)
1632  return (NUMA *)ERROR_PTR("naa not defined", procName, NULL);
1633  if (index < 0 || index >= naa->n)
1634  return (NUMA *)ERROR_PTR("index not valid", procName, NULL);
1635 
1636  if (accessflag == L_COPY)
1637  return numaCopy(naa->numa[index]);
1638  else if (accessflag == L_CLONE)
1639  return numaClone(naa->numa[index]);
1640  else
1641  return (NUMA *)ERROR_PTR("invalid accessflag", procName, NULL);
1642 }
1643 
1644 
1660 l_int32
1662  l_int32 index,
1663  NUMA *na)
1664 {
1665 l_int32 n;
1666 
1667  PROCNAME("numaaReplaceNuma");
1668 
1669  if (!naa)
1670  return ERROR_INT("naa not defined", procName, 1);
1671  if (!na)
1672  return ERROR_INT("na not defined", procName, 1);
1673  n = numaaGetCount(naa);
1674  if (index < 0 || index >= n)
1675  return ERROR_INT("index not valid", procName, 1);
1676 
1677  numaDestroy(&naa->numa[index]);
1678  naa->numa[index] = na;
1679  return 0;
1680 }
1681 
1682 
1693 l_int32
1695  l_int32 i,
1696  l_int32 j,
1697  l_float32 *pfval,
1698  l_int32 *pival)
1699 {
1700 l_int32 n;
1701 NUMA *na;
1702 
1703  PROCNAME("numaaGetValue");
1704 
1705  if (!pfval && !pival)
1706  return ERROR_INT("no return val requested", procName, 1);
1707  if (pfval) *pfval = 0.0;
1708  if (pival) *pival = 0;
1709  if (!naa)
1710  return ERROR_INT("naa not defined", procName, 1);
1711  n = numaaGetCount(naa);
1712  if (i < 0 || i >= n)
1713  return ERROR_INT("invalid index into naa", procName, 1);
1714  na = naa->numa[i];
1715  if (j < 0 || j >= na->n)
1716  return ERROR_INT("invalid index into na", procName, 1);
1717  if (pfval) *pfval = na->array[j];
1718  if (pival) *pival = (l_int32)(na->array[j]);
1719  return 0;
1720 }
1721 
1722 
1736 l_int32
1738  l_int32 index,
1739  l_float32 val)
1740 {
1741 l_int32 n;
1742 NUMA *na;
1743 
1744  PROCNAME("numaaAddNumber");
1745 
1746  if (!naa)
1747  return ERROR_INT("naa not defined", procName, 1);
1748  n = numaaGetCount(naa);
1749  if (index < 0 || index >= n)
1750  return ERROR_INT("invalid index in naa", procName, 1);
1751 
1752  na = numaaGetNuma(naa, index, L_CLONE);
1753  numaAddNumber(na, val);
1754  numaDestroy(&na);
1755  return 0;
1756 }
1757 
1758 
1759 /*----------------------------------------------------------------------*
1760  * Serialize numaa for I/O *
1761  *----------------------------------------------------------------------*/
1768 NUMAA *
1769 numaaRead(const char *filename)
1770 {
1771 FILE *fp;
1772 NUMAA *naa;
1773 
1774  PROCNAME("numaaRead");
1775 
1776  if (!filename)
1777  return (NUMAA *)ERROR_PTR("filename not defined", procName, NULL);
1778 
1779  if ((fp = fopenReadStream(filename)) == NULL)
1780  return (NUMAA *)ERROR_PTR("stream not opened", procName, NULL);
1781  naa = numaaReadStream(fp);
1782  fclose(fp);
1783  if (!naa)
1784  return (NUMAA *)ERROR_PTR("naa not read", procName, NULL);
1785  return naa;
1786 }
1787 
1788 
1795 NUMAA *
1797 {
1798 l_int32 i, n, index, ret, version;
1799 NUMA *na;
1800 NUMAA *naa;
1801 
1802  PROCNAME("numaaReadStream");
1803 
1804  if (!fp)
1805  return (NUMAA *)ERROR_PTR("stream not defined", procName, NULL);
1806 
1807  ret = fscanf(fp, "\nNumaa Version %d\n", &version);
1808  if (ret != 1)
1809  return (NUMAA *)ERROR_PTR("not a numa file", procName, NULL);
1810  if (version != NUMA_VERSION_NUMBER)
1811  return (NUMAA *)ERROR_PTR("invalid numaa version", procName, NULL);
1812  if (fscanf(fp, "Number of numa = %d\n\n", &n) != 1)
1813  return (NUMAA *)ERROR_PTR("invalid number of numa", procName, NULL);
1814  if ((naa = numaaCreate(n)) == NULL)
1815  return (NUMAA *)ERROR_PTR("naa not made", procName, NULL);
1816 
1817  for (i = 0; i < n; i++) {
1818  if (fscanf(fp, "Numa[%d]:", &index) != 1) {
1819  numaaDestroy(&naa);
1820  return (NUMAA *)ERROR_PTR("invalid numa header", procName, NULL);
1821  }
1822  if ((na = numaReadStream(fp)) == NULL) {
1823  numaaDestroy(&naa);
1824  return (NUMAA *)ERROR_PTR("na not made", procName, NULL);
1825  }
1826  numaaAddNuma(naa, na, L_INSERT);
1827  }
1828 
1829  return naa;
1830 }
1831 
1832 
1840 NUMAA *
1841 numaaReadMem(const l_uint8 *data,
1842  size_t size)
1843 {
1844 FILE *fp;
1845 NUMAA *naa;
1846 
1847  PROCNAME("numaaReadMem");
1848 
1849  if (!data)
1850  return (NUMAA *)ERROR_PTR("data not defined", procName, NULL);
1851  if ((fp = fopenReadFromMemory(data, size)) == NULL)
1852  return (NUMAA *)ERROR_PTR("stream not opened", procName, NULL);
1853 
1854  naa = numaaReadStream(fp);
1855  fclose(fp);
1856  if (!naa) L_ERROR("naa not read\n", procName);
1857  return naa;
1858 }
1859 
1860 
1867 l_int32
1868 numaaWrite(const char *filename,
1869  NUMAA *naa)
1870 {
1871 l_int32 ret;
1872 FILE *fp;
1873 
1874  PROCNAME("numaaWrite");
1875 
1876  if (!filename)
1877  return ERROR_INT("filename not defined", procName, 1);
1878  if (!naa)
1879  return ERROR_INT("naa not defined", procName, 1);
1880 
1881  if ((fp = fopenWriteStream(filename, "w")) == NULL)
1882  return ERROR_INT("stream not opened", procName, 1);
1883  ret = numaaWriteStream(fp, naa);
1884  fclose(fp);
1885  if (ret)
1886  return ERROR_INT("naa not written to stream", procName, 1);
1887  return 0;
1888 }
1889 
1890 
1898 l_int32
1900  NUMAA *naa)
1901 {
1902 l_int32 i, n;
1903 NUMA *na;
1904 
1905  PROCNAME("numaaWriteStream");
1906 
1907  if (!fp)
1908  return ERROR_INT("stream not defined", procName, 1);
1909  if (!naa)
1910  return ERROR_INT("naa not defined", procName, 1);
1911 
1912  n = numaaGetCount(naa);
1913  fprintf(fp, "\nNumaa Version %d\n", NUMA_VERSION_NUMBER);
1914  fprintf(fp, "Number of numa = %d\n\n", n);
1915  for (i = 0; i < n; i++) {
1916  if ((na = numaaGetNuma(naa, i, L_CLONE)) == NULL)
1917  return ERROR_INT("na not found", procName, 1);
1918  fprintf(fp, "Numa[%d]:", i);
1919  numaWriteStream(fp, na);
1920  numaDestroy(&na);
1921  }
1922 
1923  return 0;
1924 }
1925 
1926 
1940 l_int32
1941 numaaWriteMem(l_uint8 **pdata,
1942  size_t *psize,
1943  NUMAA *naa)
1944 {
1945 l_int32 ret;
1946 FILE *fp;
1947 
1948  PROCNAME("numaaWriteMem");
1949 
1950  if (pdata) *pdata = NULL;
1951  if (psize) *psize = 0;
1952  if (!pdata)
1953  return ERROR_INT("&data not defined", procName, 1);
1954  if (!psize)
1955  return ERROR_INT("&size not defined", procName, 1);
1956  if (!naa)
1957  return ERROR_INT("naa not defined", procName, 1);
1958 
1959 #if HAVE_FMEMOPEN
1960  if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1961  return ERROR_INT("stream not opened", procName, 1);
1962  ret = numaaWriteStream(fp, naa);
1963 #else
1964  L_INFO("work-around: writing to a temp file\n", procName);
1965  #ifdef _WIN32
1966  if ((fp = fopenWriteWinTempfile()) == NULL)
1967  return ERROR_INT("tmpfile stream not opened", procName, 1);
1968  #else
1969  if ((fp = tmpfile()) == NULL)
1970  return ERROR_INT("tmpfile stream not opened", procName, 1);
1971  #endif /* _WIN32 */
1972  ret = numaaWriteStream(fp, naa);
1973  rewind(fp);
1974  *pdata = l_binaryReadStream(fp, psize);
1975 #endif /* HAVE_FMEMOPEN */
1976  fclose(fp);
1977  return ret;
1978 }
1979 
l_int32 numaaReplaceNuma(NUMAA *naa, l_int32 index, NUMA *na)
numaaReplaceNuma()
Definition: numabasic.c:1661
NUMAA * numaaReadMem(const l_uint8 *data, size_t size)
numaaReadMem()
Definition: numabasic.c:1841
NUMAA * numaaRead(const char *filename)
numaaRead()
Definition: numabasic.c:1769
l_int32 numaaWriteMem(l_uint8 **pdata, size_t *psize, NUMAA *naa)
numaaWriteMem()
Definition: numabasic.c:1941
l_int32 numaShiftValue(NUMA *na, l_int32 index, l_float32 diff)
numaShiftValue()
Definition: numabasic.c:783
l_int32 numaSetCount(NUMA *na, l_int32 newcount)
numaSetCount()
Definition: numabasic.c:657
NUMAA * numaaReadStream(FILE *fp)
numaaReadStream()
Definition: numabasic.c:1796
NUMA * numaReadMem(const l_uint8 *data, size_t size)
numaReadMem()
Definition: numabasic.c:1155
l_int32 numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:472
l_float32 ** data
Definition: morph.h:95
struct Numa ** numa
Definition: array.h:75
NUMA ** numaaGetPtrArray(NUMAA *naa)
numaaGetPtrArray()
Definition: numabasic.c:1604
NUMA * numaRead(const char *filename)
numaRead()
Definition: numabasic.c:1082
l_int32 numaaWriteStream(FILE *fp, NUMAA *naa)
numaaWriteStream()
Definition: numabasic.c:1899
l_int32 numaaGetNumberCount(NUMAA *naa)
numaaGetNumberCount()
Definition: numabasic.c:1555
Definition: pix.h:704
l_int32 nalloc
Definition: array.h:73
l_int32 refcount
Definition: array.h:63
l_float32 startx
Definition: array.h:64
l_int32 numaGetFValue(NUMA *na, l_int32 index, l_float32 *pval)
numaGetFValue()
Definition: numabasic.c:691
l_int32 nalloc
Definition: array.h:61
SARRAY * sarrayCreate(l_int32 n)
sarrayCreate()
Definition: sarray1.c:157
FILE * fopenReadFromMemory(const l_uint8 *data, size_t size)
fopenReadFromMemory()
Definition: utils2.c:1670
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:186
l_float32 delx
Definition: array.h:65
l_int32 numaGetParameters(NUMA *na, l_float32 *pstartx, l_float32 *pdelx)
numaGetParameters()
Definition: numabasic.c:935
NUMAA * numaaCreate(l_int32 n)
numaaCreate()
Definition: numabasic.c:1307
void * reallocNew(void **pindata, l_int32 oldsize, l_int32 newsize)
reallocNew()
Definition: utils2.c:1102
l_int32 numaInsertNumber(NUMA *na, l_int32 index, l_float32 val)
numaInsertNumber()
Definition: numabasic.c:533
l_int32 numaaAddNumber(NUMAA *naa, l_int32 index, l_float32 val)
numaaAddNumber()
Definition: numabasic.c:1737
void numaaDestroy(NUMAA **pnaa)
numaaDestroy()
Definition: numabasic.c:1410
l_int32 numaRemoveNumber(NUMA *na, l_int32 index)
numaRemoveNumber()
Definition: numabasic.c:572
Definition: array.h:116
l_int32 numaWriteMem(l_uint8 **pdata, size_t *psize, NUMA *na)
numaWriteMem()
Definition: numabasic.c:1256
l_int32 numaaAddNuma(NUMAA *naa, NUMA *na, l_int32 copyflag)
numaaAddNuma()
Definition: numabasic.c:1448
l_int32 numaGetRefcount(NUMA *na)
numaGetRefCount()
Definition: numabasic.c:896
l_int32 * numaGetIArray(NUMA *na)
numaGetIArray()
Definition: numabasic.c:819
NUMA * numaaGetNuma(NUMAA *naa, l_int32 index, l_int32 accessflag)
numaaGetNuma()
Definition: numabasic.c:1625
Definition: array.h:59
static const l_int32 L_INSERT
Definition: pix.h:710
l_int32 numaGetCount(NUMA *na)
numaGetCount()
Definition: numabasic.c:630
l_float32 * array
Definition: array.h:66
FILE * fopenWriteWinTempfile()
fopenWriteWinTempfile()
Definition: utils2.c:1716
char * sarrayGetString(SARRAY *sa, l_int32 index, l_int32 copyflag)
sarrayGetString()
Definition: sarray1.c:675
l_int32 sarrayAddString(SARRAY *sa, char *string, l_int32 copyflag)
sarrayAddString()
Definition: sarray1.c:439
Definition: array.h:71
NUMA * numaCreateFromIArray(l_int32 *iarray, l_int32 size)
numaCreateFromIArray()
Definition: numabasic.c:227
l_int32 numaEmpty(NUMA *na)
numaEmpty()
Definition: numabasic.c:448
l_int32 numaSetParameters(NUMA *na, l_float32 startx, l_float32 delx)
numaSetParameters()
Definition: numabasic.c:965
NUMA * numaCopy(NUMA *na)
numaCopy()
Definition: numabasic.c:393
NUMA * numaCreateFromString(const char *str)
numaCreateFromString()
Definition: numabasic.c:308
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:359
#define NUMA_VERSION_NUMBER
Definition: array.h:56
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1636
FILE * fopenReadStream(const char *filename)
fopenReadStream()
Definition: utils2.c:1593
l_uint8 * l_binaryReadStream(FILE *fp, size_t *pnbytes)
l_binaryReadStream()
Definition: utils2.c:1200
l_int32 numaCopyParameters(NUMA *nad, NUMA *nas)
numaCopyParameters()
Definition: numabasic.c:988
l_int32 sarrayGetCount(SARRAY *sa)
sarrayGetCount()
Definition: sarray1.c:615
l_int32 numaReplaceNumber(NUMA *na, l_int32 index, l_float32 val)
numaReplaceNumber()
Definition: numabasic.c:601
l_int32 n
Definition: array.h:74
l_float32 * numaGetFArray(NUMA *na, l_int32 copyflag)
numaGetFArray()
Definition: numabasic.c:864
l_int32 n
Definition: array.h:62
l_int32 numaWrite(const char *filename, NUMA *na)
numaWrite()
Definition: numabasic.c:1182
l_int32 numaaGetCount(NUMAA *naa)
numaaGetCount()
Definition: numabasic.c:1516
l_int32 numaaTruncate(NUMAA *naa)
numaaTruncate()
Definition: numabasic.c:1376
l_int32 numaaGetNumaCount(NUMAA *naa, l_int32 index)
numaaGetNumaCount()
Definition: numabasic.c:1534
Definition: pix.h:705
static l_int32 numaExtendArray(NUMA *na)
numaExtendArray()
Definition: numabasic.c:498
l_int32 numaSetValue(NUMA *na, l_int32 index, l_float32 val)
numaSetValue()
Definition: numabasic.c:758
Definition: pix.h:706
l_int32 numaaGetValue(NUMAA *naa, l_int32 i, l_int32 j, l_float32 *pfval, l_int32 *pival)
numaaGetValue()
Definition: numabasic.c:1694
l_int32 numaaWrite(const char *filename, NUMAA *naa)
numaaWrite()
Definition: numabasic.c:1868
static l_int32 numaaExtendArray(NUMAA *naa)
numaaExtendArray()
Definition: numabasic.c:1489
NUMA * numaClone(NUMA *na)
numaClone()
Definition: numabasic.c:422
NUMAA * numaaCreateFull(l_int32 nptr, l_int32 n)
numaaCreateFull()
Definition: numabasic.c:1345
l_int32 numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition: numabasic.c:726
NUMA * numaCreateFromFArray(l_float32 *farray, l_int32 size, l_int32 copyflag)
numaCreateFromFArray()
Definition: numabasic.c:264
SARRAY * numaConvertToSarray(NUMA *na, l_int32 size1, l_int32 size2, l_int32 addzeros, l_int32 type)
numaConvertToSarray()
Definition: numabasic.c:1026
l_int32 numaChangeRefcount(NUMA *na, l_int32 delta)
numaChangeRefCount()
Definition: numabasic.c:914
NUMA * numaReadStream(FILE *fp)
numaReadStream()
Definition: numabasic.c:1109
void sarrayDestroy(SARRAY **psa)
sarrayDestroy()
Definition: sarray1.c:349
l_int32 numaWriteStream(FILE *fp, NUMA *na)
numaWriteStream()
Definition: numabasic.c:1213