Leptonica  1.83.1
Image processing and image analysis suite
dnabasic.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 
151 #ifdef HAVE_CONFIG_H
152 #include <config_auto.h>
153 #endif /* HAVE_CONFIG_H */
154 
155 #include <string.h>
156 #include <math.h>
157 #include "allheaders.h"
158 #include "array_internal.h"
159 
160  /* Bounds on initial array size */
161 static const l_uint32 MaxDoubleArraySize = 100000000; /* for dna */
162 static const l_uint32 MaxPtrArraySize = 1000000; /* for dnaa */
163 static const l_int32 InitialArraySize = 50;
165  /* Static functions */
166 static l_int32 l_dnaExtendArray(L_DNA *da);
167 static l_int32 l_dnaaExtendArray(L_DNAA *daa);
168 
169 /*--------------------------------------------------------------------------*
170  * Dna creation, destruction, copy, clone, etc. *
171  *--------------------------------------------------------------------------*/
178 L_DNA *
179 l_dnaCreate(l_int32 n)
180 {
181 L_DNA *da;
182 
183  if (n <= 0 || n > MaxDoubleArraySize)
184  n = InitialArraySize;
185 
186  da = (L_DNA *)LEPT_CALLOC(1, sizeof(L_DNA));
187  if ((da->array = (l_float64 *)LEPT_CALLOC(n, sizeof(l_float64))) == NULL) {
188  l_dnaDestroy(&da);
189  return (L_DNA *)ERROR_PTR("double array not made", __func__, NULL);
190  }
191 
192  da->nalloc = n;
193  da->n = 0;
194  da->refcount = 1;
195  da->startx = 0.0;
196  da->delx = 1.0;
197 
198  return da;
199 }
200 
201 
217 L_DNA *
218 l_dnaCreateFromIArray(l_int32 *iarray,
219  l_int32 size)
220 {
221 l_int32 i;
222 L_DNA *da;
223 
224  if (!iarray)
225  return (L_DNA *)ERROR_PTR("iarray not defined", __func__, NULL);
226  if (size <= 0)
227  return (L_DNA *)ERROR_PTR("size must be > 0", __func__, NULL);
228 
229  da = l_dnaCreate(size);
230  for (i = 0; i < size; i++)
231  l_dnaAddNumber(da, iarray[i]);
232 
233  return da;
234 }
235 
236 
252 L_DNA *
253 l_dnaCreateFromDArray(l_float64 *darray,
254  l_int32 size,
255  l_int32 copyflag)
256 {
257 l_int32 i;
258 L_DNA *da;
259 
260  if (!darray)
261  return (L_DNA *)ERROR_PTR("darray not defined", __func__, NULL);
262  if (size <= 0)
263  return (L_DNA *)ERROR_PTR("size must be > 0", __func__, NULL);
264  if (copyflag != L_INSERT && copyflag != L_COPY)
265  return (L_DNA *)ERROR_PTR("invalid copyflag", __func__, NULL);
266 
267  da = l_dnaCreate(size);
268  if (copyflag == L_INSERT) {
269  if (da->array) LEPT_FREE(da->array);
270  da->array = darray;
271  da->n = size;
272  } else { /* just copy the contents */
273  for (i = 0; i < size; i++)
274  l_dnaAddNumber(da, darray[i]);
275  }
276 
277  return da;
278 }
279 
280 
289 L_DNA *
290 l_dnaMakeSequence(l_float64 startval,
291  l_float64 increment,
292  l_int32 size)
293 {
294 l_int32 i;
295 l_float64 val;
296 L_DNA *da;
297 
298  if ((da = l_dnaCreate(size)) == NULL)
299  return (L_DNA *)ERROR_PTR("da not made", __func__, NULL);
300 
301  for (i = 0; i < size; i++) {
302  val = startval + i * increment;
303  l_dnaAddNumber(da, val);
304  }
305 
306  return da;
307 }
308 
309 
322 void
324 {
325 L_DNA *da;
326 
327  if (pda == NULL) {
328  L_WARNING("ptr address is NULL\n", __func__);
329  return;
330  }
331 
332  if ((da = *pda) == NULL)
333  return;
334 
335  /* Decrement the ref count. If it is 0, destroy the l_dna. */
336  if (--da->refcount == 0) {
337  if (da->array)
338  LEPT_FREE(da->array);
339  LEPT_FREE(da);
340  }
341  *pda = NULL;
342 }
343 
344 
356 L_DNA *
358 {
359 l_int32 i;
360 L_DNA *dac;
361 
362  if (!da)
363  return (L_DNA *)ERROR_PTR("da not defined", __func__, NULL);
364 
365  if ((dac = l_dnaCreate(da->n)) == NULL)
366  return (L_DNA *)ERROR_PTR("dac not made", __func__, NULL);
367  dac->startx = da->startx;
368  dac->delx = da->delx;
369 
370  for (i = 0; i < da->n; i++)
371  l_dnaAddNumber(dac, da->array[i]);
372 
373  return dac;
374 }
375 
376 
383 L_DNA *
385 {
386  if (!da)
387  return (L_DNA *)ERROR_PTR("da not defined", __func__, NULL);
388 
389  ++da->refcount;
390  return da;
391 }
392 
393 
407 l_ok
409 {
410  if (!da)
411  return ERROR_INT("da not defined", __func__, 1);
412 
413  da->n = 0;
414  return 0;
415 }
416 
417 
418 
419 /*--------------------------------------------------------------------------*
420  * Dna: add/remove number and extend array *
421  *--------------------------------------------------------------------------*/
429 l_ok
431  l_float64 val)
432 {
433 l_int32 n;
434 
435  if (!da)
436  return ERROR_INT("da not defined", __func__, 1);
437 
438  n = l_dnaGetCount(da);
439  if (n >= da->nalloc) {
440  if (l_dnaExtendArray(da))
441  return ERROR_INT("extension failed", __func__, 1);
442  }
443  da->array[n] = val;
444  da->n++;
445  return 0;
446 }
447 
448 
461 static l_int32
463 {
464 size_t oldsize, newsize;
465 
466  if (!da)
467  return ERROR_INT("da not defined", __func__, 1);
468  if (da->nalloc > MaxDoubleArraySize)
469  return ERROR_INT("da at maximum size; can't extend", __func__, 1);
470  oldsize = da->nalloc * sizeof(l_float64);
471  if (da->nalloc > MaxDoubleArraySize / 2) {
472  newsize = MaxDoubleArraySize * sizeof(l_float64);
473  da->nalloc = MaxDoubleArraySize;
474  } else {
475  newsize = 2 * oldsize;
476  da->nalloc *= 2;
477  }
478  if ((da->array = (l_float64 *)reallocNew((void **)&da->array,
479  oldsize, newsize)) == NULL)
480  return ERROR_INT("new ptr array not returned", __func__, 1);
481 
482  return 0;
483 }
484 
485 
503 l_ok
505  l_int32 index,
506  l_float64 val)
507 {
508 l_int32 i, n;
509 
510  if (!da)
511  return ERROR_INT("da not defined", __func__, 1);
512  n = l_dnaGetCount(da);
513  if (index < 0 || index > n) {
514  L_ERROR("index %d not in [0,...,%d]\n", __func__, index, n);
515  return 1;
516  }
517 
518  if (n >= da->nalloc) {
519  if (l_dnaExtendArray(da))
520  return ERROR_INT("extension failed", __func__, 1);
521  }
522  for (i = n; i > index; i--)
523  da->array[i] = da->array[i - 1];
524  da->array[index] = val;
525  da->n++;
526  return 0;
527 }
528 
529 
544 l_ok
546  l_int32 index)
547 {
548 l_int32 i, n;
549 
550  if (!da)
551  return ERROR_INT("da not defined", __func__, 1);
552  n = l_dnaGetCount(da);
553  if (index < 0 || index >= n) {
554  L_ERROR("index %d not in [0,...,%d]\n", __func__, index, n - 1);
555  return 1;
556  }
557 
558  for (i = index + 1; i < n; i++)
559  da->array[i - 1] = da->array[i];
560  da->n--;
561  return 0;
562 }
563 
564 
573 l_ok
575  l_int32 index,
576  l_float64 val)
577 {
578 l_int32 n;
579 
580  if (!da)
581  return ERROR_INT("da not defined", __func__, 1);
582  n = l_dnaGetCount(da);
583  if (index < 0 || index >= n) {
584  L_ERROR("index %d not in [0,...,%d]\n", __func__, index, n - 1);
585  return 1;
586  }
587 
588  da->array[index] = val;
589  return 0;
590 }
591 
592 
593 /*----------------------------------------------------------------------*
594  * Dna accessors *
595  *----------------------------------------------------------------------*/
602 l_int32
604 {
605  if (!da)
606  return ERROR_INT("da not defined", __func__, 0);
607  return da->n;
608 }
609 
610 
627 l_ok
629  l_int32 newcount)
630 {
631  if (!da)
632  return ERROR_INT("da not defined", __func__, 1);
633  if (newcount > da->nalloc) {
634  if ((da->array = (l_float64 *)reallocNew((void **)&da->array,
635  sizeof(l_float64) * da->nalloc,
636  sizeof(l_float64) * newcount)) == NULL)
637  return ERROR_INT("new ptr array not returned", __func__, 1);
638  da->nalloc = newcount;
639  }
640  da->n = newcount;
641  return 0;
642 }
643 
644 
659 l_ok
661  l_int32 index,
662  l_float64 *pval)
663 {
664  if (!pval)
665  return ERROR_INT("&val not defined", __func__, 1);
666  *pval = 0.0;
667  if (!da)
668  return ERROR_INT("da not defined", __func__, 1);
669 
670  if (index < 0 || index >= da->n)
671  return ERROR_INT("index not valid", __func__, 1);
672 
673  *pval = da->array[index];
674  return 0;
675 }
676 
677 
692 l_ok
694  l_int32 index,
695  l_int32 *pival)
696 {
697 l_float64 val;
698 
699  if (!pival)
700  return ERROR_INT("&ival not defined", __func__, 1);
701  *pival = 0;
702  if (!da)
703  return ERROR_INT("da not defined", __func__, 1);
704 
705  if (index < 0 || index >= da->n)
706  return ERROR_INT("index not valid", __func__, 1);
707 
708  val = da->array[index];
709  *pival = (l_int32)(val + L_SIGN(val) * 0.5);
710  return 0;
711 }
712 
713 
722 l_ok
724  l_int32 index,
725  l_float64 val)
726 {
727  if (!da)
728  return ERROR_INT("da not defined", __func__, 1);
729  if (index < 0 || index >= da->n)
730  return ERROR_INT("index not valid", __func__, 1);
731 
732  da->array[index] = val;
733  return 0;
734 }
735 
736 
745 l_ok
747  l_int32 index,
748  l_float64 diff)
749 {
750  if (!da)
751  return ERROR_INT("da not defined", __func__, 1);
752  if (index < 0 || index >= da->n)
753  return ERROR_INT("index not valid", __func__, 1);
754 
755  da->array[index] += diff;
756  return 0;
757 }
758 
759 
779 l_int32 *
781 {
782 l_int32 i, n, ival;
783 l_int32 *array;
784 
785  if (!da)
786  return (l_int32 *)ERROR_PTR("da not defined", __func__, NULL);
787 
788  n = l_dnaGetCount(da);
789  if ((array = (l_int32 *)LEPT_CALLOC(n, sizeof(l_int32))) == NULL)
790  return (l_int32 *)ERROR_PTR("array not made", __func__, NULL);
791  for (i = 0; i < n; i++) {
792  l_dnaGetIValue(da, i, &ival);
793  array[i] = ival;
794  }
795 
796  return array;
797 }
798 
799 
821 l_float64 *
823  l_int32 copyflag)
824 {
825 l_int32 i, n;
826 l_float64 *array;
827 
828  if (!da)
829  return (l_float64 *)ERROR_PTR("da not defined", __func__, NULL);
830 
831  if (copyflag == L_NOCOPY) {
832  array = da->array;
833  } else { /* copyflag == L_COPY */
834  n = l_dnaGetCount(da);
835  if ((array = (l_float64 *)LEPT_CALLOC(n, sizeof(l_float64))) == NULL)
836  return (l_float64 *)ERROR_PTR("array not made", __func__, NULL);
837  for (i = 0; i < n; i++)
838  array[i] = da->array[i];
839  }
840 
841  return array;
842 }
843 
844 
853 l_ok
855  l_float64 *pstartx,
856  l_float64 *pdelx)
857 {
858  if (pstartx) *pstartx = 0.0;
859  if (pdelx) *pdelx = 1.0;
860  if (!pstartx && !pdelx)
861  return ERROR_INT("neither &startx nor &delx are defined", __func__, 1);
862  if (!da)
863  return ERROR_INT("da not defined", __func__, 1);
864 
865  if (pstartx) *pstartx = da->startx;
866  if (pdelx) *pdelx = da->delx;
867  return 0;
868 }
869 
870 
881 l_ok
883  l_float64 startx,
884  l_float64 delx)
885 {
886  if (!da)
887  return ERROR_INT("da not defined", __func__, 1);
888 
889  da->startx = startx;
890  da->delx = delx;
891  return 0;
892 }
893 
894 
902 l_ok
904  L_DNA *das)
905 {
906 l_float64 start, binsize;
907 
908  if (!das || !dad)
909  return ERROR_INT("das and dad not both defined", __func__, 1);
910 
911  l_dnaGetParameters(das, &start, &binsize);
912  l_dnaSetParameters(dad, start, binsize);
913  return 0;
914 }
915 
916 
917 /*----------------------------------------------------------------------*
918  * Serialize Dna for I/O *
919  *----------------------------------------------------------------------*/
926 L_DNA *
927 l_dnaRead(const char *filename)
928 {
929 FILE *fp;
930 L_DNA *da;
931 
932  if (!filename)
933  return (L_DNA *)ERROR_PTR("filename not defined", __func__, NULL);
934 
935  if ((fp = fopenReadStream(filename)) == NULL)
936  return (L_DNA *)ERROR_PTR("stream not opened", __func__, NULL);
937  da = l_dnaReadStream(fp);
938  fclose(fp);
939  if (!da)
940  return (L_DNA *)ERROR_PTR("da not read", __func__, NULL);
941  return da;
942 }
943 
944 
957 L_DNA *
959 {
960 l_int32 i, n, index, ret, version;
961 l_float64 val, startx, delx;
962 L_DNA *da;
963 
964  if (!fp)
965  return (L_DNA *)ERROR_PTR("stream not defined", __func__, NULL);
966 
967  ret = fscanf(fp, "\nL_Dna Version %d\n", &version);
968  if (ret != 1)
969  return (L_DNA *)ERROR_PTR("not a l_dna file", __func__, NULL);
970  if (version != DNA_VERSION_NUMBER)
971  return (L_DNA *)ERROR_PTR("invalid l_dna version", __func__, NULL);
972  if (fscanf(fp, "Number of numbers = %d\n", &n) != 1)
973  return (L_DNA *)ERROR_PTR("invalid number of numbers", __func__, NULL);
974  if (n < 0)
975  return (L_DNA *)ERROR_PTR("num doubles < 0", __func__, NULL);
976  if (n > MaxDoubleArraySize)
977  return (L_DNA *)ERROR_PTR("too many doubles", __func__, NULL);
978  if (n == 0) L_INFO("the dna is empty\n", __func__);
979 
980  if ((da = l_dnaCreate(n)) == NULL)
981  return (L_DNA *)ERROR_PTR("da not made", __func__, NULL);
982  for (i = 0; i < n; i++) {
983  if (fscanf(fp, " [%d] = %lf\n", &index, &val) != 2) {
984  l_dnaDestroy(&da);
985  return (L_DNA *)ERROR_PTR("bad input data", __func__, NULL);
986  }
987  l_dnaAddNumber(da, val);
988  }
989 
990  /* Optional data */
991  if (fscanf(fp, "startx = %lf, delx = %lf\n", &startx, &delx) == 2)
992  l_dnaSetParameters(da, startx, delx);
993  return da;
994 }
995 
996 
1004 L_DNA *
1005 l_dnaReadMem(const l_uint8 *data,
1006  size_t size)
1007 {
1008 FILE *fp;
1009 L_DNA *da;
1010 
1011  if (!data)
1012  return (L_DNA *)ERROR_PTR("data not defined", __func__, NULL);
1013  if ((fp = fopenReadFromMemory(data, size)) == NULL)
1014  return (L_DNA *)ERROR_PTR("stream not opened", __func__, NULL);
1015 
1016  da = l_dnaReadStream(fp);
1017  fclose(fp);
1018  if (!da) L_ERROR("dna not read\n", __func__);
1019  return da;
1020 }
1021 
1022 
1030 l_ok
1031 l_dnaWrite(const char *filename,
1032  L_DNA *da)
1033 {
1034 l_int32 ret;
1035 FILE *fp;
1036 
1037  if (!filename)
1038  return ERROR_INT("filename not defined", __func__, 1);
1039  if (!da)
1040  return ERROR_INT("da not defined", __func__, 1);
1041 
1042  if ((fp = fopenWriteStream(filename, "w")) == NULL)
1043  return ERROR_INT("stream not opened", __func__, 1);
1044  ret = l_dnaWriteStream(fp, da);
1045  fclose(fp);
1046  if (ret)
1047  return ERROR_INT("da not written to stream", __func__, 1);
1048  return 0;
1049 }
1050 
1051 
1059 l_ok
1061  L_DNA *da)
1062 {
1063 l_int32 i, n;
1064 l_float64 startx, delx;
1065 
1066  if (!da)
1067  return ERROR_INT("da not defined", __func__, 1);
1068  if (!fp)
1069  return l_dnaWriteStderr(da);
1070 
1071  n = l_dnaGetCount(da);
1072  fprintf(fp, "\nL_Dna Version %d\n", DNA_VERSION_NUMBER);
1073  fprintf(fp, "Number of numbers = %d\n", n);
1074  for (i = 0; i < n; i++)
1075  fprintf(fp, " [%d] = %f\n", i, da->array[i]);
1076  fprintf(fp, "\n");
1077 
1078  /* Optional data */
1079  l_dnaGetParameters(da, &startx, &delx);
1080  if (startx != 0.0 || delx != 1.0)
1081  fprintf(fp, "startx = %f, delx = %f\n", startx, delx);
1082 
1083  return 0;
1084 }
1085 
1086 
1093 l_ok
1095 {
1096 l_int32 i, n;
1097 l_float64 startx, delx;
1098 
1099  if (!da)
1100  return ERROR_INT("da not defined", __func__, 1);
1101 
1102  n = l_dnaGetCount(da);
1103  lept_stderr("\nL_Dna Version %d\n", DNA_VERSION_NUMBER);
1104  lept_stderr("Number of numbers = %d\n", n);
1105  for (i = 0; i < n; i++)
1106  lept_stderr(" [%d] = %f\n", i, da->array[i]);
1107  lept_stderr("\n");
1108 
1109  /* Optional data */
1110  l_dnaGetParameters(da, &startx, &delx);
1111  if (startx != 0.0 || delx != 1.0)
1112  lept_stderr("startx = %f, delx = %f\n", startx, delx);
1113 
1114  return 0;
1115 }
1116 
1117 
1131 l_ok
1132 l_dnaWriteMem(l_uint8 **pdata,
1133  size_t *psize,
1134  L_DNA *da)
1135 {
1136 l_int32 ret;
1137 FILE *fp;
1138 
1139  if (pdata) *pdata = NULL;
1140  if (psize) *psize = 0;
1141  if (!pdata)
1142  return ERROR_INT("&data not defined", __func__, 1);
1143  if (!psize)
1144  return ERROR_INT("&size not defined", __func__, 1);
1145  if (!da)
1146  return ERROR_INT("da not defined", __func__, 1);
1147 
1148 #if HAVE_FMEMOPEN
1149  if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1150  return ERROR_INT("stream not opened", __func__, 1);
1151  ret = l_dnaWriteStream(fp, da);
1152  fputc('\0', fp);
1153  fclose(fp);
1154  *psize = *psize - 1;
1155 #else
1156  L_INFO("work-around: writing to a temp file\n", __func__);
1157  #ifdef _WIN32
1158  if ((fp = fopenWriteWinTempfile()) == NULL)
1159  return ERROR_INT("tmpfile stream not opened", __func__, 1);
1160  #else
1161  if ((fp = tmpfile()) == NULL)
1162  return ERROR_INT("tmpfile stream not opened", __func__, 1);
1163  #endif /* _WIN32 */
1164  ret = l_dnaWriteStream(fp, da);
1165  rewind(fp);
1166  *pdata = l_binaryReadStream(fp, psize);
1167  fclose(fp);
1168 #endif /* HAVE_FMEMOPEN */
1169  return ret;
1170 }
1171 
1172 
1173 /*--------------------------------------------------------------------------*
1174  * Dnaa creation, destruction *
1175  *--------------------------------------------------------------------------*/
1183 L_DNAA *
1184 l_dnaaCreate(l_int32 n)
1185 {
1186 L_DNAA *daa;
1187 
1188  if (n <= 0 || n > MaxPtrArraySize)
1189  n = InitialArraySize;
1190 
1191  daa = (L_DNAA *)LEPT_CALLOC(1, sizeof(L_DNAA));
1192  if ((daa->dna = (L_DNA **)LEPT_CALLOC(n, sizeof(L_DNA *))) == NULL) {
1193  l_dnaaDestroy(&daa);
1194  return (L_DNAA *)ERROR_PTR("l_dna ptr array not made", __func__, NULL);
1195  }
1196  daa->nalloc = n;
1197  daa->n = 0;
1198  return daa;
1199 }
1200 
1201 
1217 L_DNAA *
1218 l_dnaaCreateFull(l_int32 nptr,
1219  l_int32 n)
1220 {
1221 l_int32 i;
1222 L_DNAA *daa;
1223 L_DNA *da;
1224 
1225  daa = l_dnaaCreate(nptr);
1226  for (i = 0; i < nptr; i++) {
1227  da = l_dnaCreate(n);
1228  l_dnaaAddDna(daa, da, L_INSERT);
1229  }
1230 
1231  return daa;
1232 }
1233 
1234 
1248 l_ok
1250 {
1251 l_int32 i, n, nn;
1252 L_DNA *da;
1253 
1254  if (!daa)
1255  return ERROR_INT("daa not defined", __func__, 1);
1256 
1257  n = l_dnaaGetCount(daa);
1258  for (i = n - 1; i >= 0; i--) {
1259  da = l_dnaaGetDna(daa, i, L_CLONE);
1260  if (!da)
1261  continue;
1262  nn = l_dnaGetCount(da);
1263  l_dnaDestroy(&da); /* the clone */
1264  if (nn == 0)
1265  l_dnaDestroy(&daa->dna[i]);
1266  else
1267  break;
1268  }
1269  daa->n = i + 1;
1270  return 0;
1271 }
1272 
1273 
1280 void
1282 {
1283 l_int32 i;
1284 L_DNAA *daa;
1285 
1286  if (pdaa == NULL) {
1287  L_WARNING("ptr address is NULL!\n", __func__);
1288  return;
1289  }
1290 
1291  if ((daa = *pdaa) == NULL)
1292  return;
1293 
1294  for (i = 0; i < daa->n; i++)
1295  l_dnaDestroy(&daa->dna[i]);
1296  LEPT_FREE(daa->dna);
1297  LEPT_FREE(daa);
1298  *pdaa = NULL;
1299 }
1300 
1301 
1302 /*--------------------------------------------------------------------------*
1303  * Add Dna to Dnaa *
1304  *--------------------------------------------------------------------------*/
1313 l_ok
1315  L_DNA *da,
1316  l_int32 copyflag)
1317 {
1318 l_int32 n;
1319 L_DNA *dac;
1320 
1321  if (!daa)
1322  return ERROR_INT("daa not defined", __func__, 1);
1323  if (!da)
1324  return ERROR_INT("da not defined", __func__, 1);
1325 
1326  if (copyflag == L_INSERT) {
1327  dac = da;
1328  } else if (copyflag == L_COPY) {
1329  if ((dac = l_dnaCopy(da)) == NULL)
1330  return ERROR_INT("dac not made", __func__, 1);
1331  } else if (copyflag == L_CLONE) {
1332  dac = l_dnaClone(da);
1333  } else {
1334  return ERROR_INT("invalid copyflag", __func__, 1);
1335  }
1336 
1337  n = l_dnaaGetCount(daa);
1338  if (n >= daa->nalloc) {
1339  if (l_dnaaExtendArray(daa)) {
1340  if (copyflag != L_INSERT)
1341  l_dnaDestroy(&dac);
1342  return ERROR_INT("extension failed", __func__, 1);
1343  }
1344  }
1345  daa->dna[n] = dac;
1346  daa->n++;
1347  return 0;
1348 }
1349 
1350 
1363 static l_int32
1365 {
1366 size_t oldsize, newsize;
1367 
1368  if (!daa)
1369  return ERROR_INT("daa not defined", __func__, 1);
1370  if (daa->nalloc > MaxPtrArraySize) /* belt & suspenders */
1371  return ERROR_INT("daa has too many ptrs", __func__, 1);
1372  oldsize = daa->nalloc * sizeof(L_DNA *);
1373  newsize = 2 * oldsize;
1374  if (newsize > 8 * MaxPtrArraySize)
1375  return ERROR_INT("newsize > 8 MB; too large", __func__, 1);
1376 
1377  if ((daa->dna = (L_DNA **)reallocNew((void **)&daa->dna,
1378  oldsize, newsize)) == NULL)
1379  return ERROR_INT("new ptr array not returned", __func__, 1);
1380 
1381  daa->nalloc *= 2;
1382  return 0;
1383 }
1384 
1385 
1386 /*----------------------------------------------------------------------*
1387  * DNumaa accessors *
1388  *----------------------------------------------------------------------*/
1395 l_int32
1397 {
1398  if (!daa)
1399  return ERROR_INT("daa not defined", __func__, 0);
1400  return daa->n;
1401 }
1402 
1403 
1411 l_int32
1413  l_int32 index)
1414 {
1415  if (!daa)
1416  return ERROR_INT("daa not defined", __func__, 0);
1417  if (index < 0 || index >= daa->n)
1418  return ERROR_INT("invalid index into daa", __func__, 0);
1419  return l_dnaGetCount(daa->dna[index]);
1420 }
1421 
1422 
1430 l_int32
1432 {
1433 L_DNA *da;
1434 l_int32 n, sum, i;
1435 
1436  if (!daa)
1437  return ERROR_INT("daa not defined", __func__, 0);
1438 
1439  n = l_dnaaGetCount(daa);
1440  for (sum = 0, i = 0; i < n; i++) {
1441  da = l_dnaaGetDna(daa, i, L_CLONE);
1442  sum += l_dnaGetCount(da);
1443  l_dnaDestroy(&da);
1444  }
1445 
1446  return sum;
1447 }
1448 
1449 
1458 L_DNA *
1460  l_int32 index,
1461  l_int32 accessflag)
1462 {
1463  if (!daa)
1464  return (L_DNA *)ERROR_PTR("daa not defined", __func__, NULL);
1465  if (index < 0 || index >= daa->n)
1466  return (L_DNA *)ERROR_PTR("index not valid", __func__, NULL);
1467 
1468  if (accessflag == L_COPY)
1469  return l_dnaCopy(daa->dna[index]);
1470  else if (accessflag == L_CLONE)
1471  return l_dnaClone(daa->dna[index]);
1472  else
1473  return (L_DNA *)ERROR_PTR("invalid accessflag", __func__, NULL);
1474 }
1475 
1476 
1492 l_ok
1494  l_int32 index,
1495  L_DNA *da)
1496 {
1497 l_int32 n;
1498 
1499  if (!daa)
1500  return ERROR_INT("daa not defined", __func__, 1);
1501  if (!da)
1502  return ERROR_INT("da not defined", __func__, 1);
1503  n = l_dnaaGetCount(daa);
1504  if (index < 0 || index >= n)
1505  return ERROR_INT("index not valid", __func__, 1);
1506 
1507  l_dnaDestroy(&daa->dna[index]);
1508  daa->dna[index] = da;
1509  return 0;
1510 }
1511 
1512 
1522 l_ok
1524  l_int32 i,
1525  l_int32 j,
1526  l_float64 *pval)
1527 {
1528 l_int32 n;
1529 L_DNA *da;
1530 
1531  if (!pval)
1532  return ERROR_INT("&val not defined", __func__, 1);
1533  *pval = 0.0;
1534  if (!daa)
1535  return ERROR_INT("daa not defined", __func__, 1);
1536  n = l_dnaaGetCount(daa);
1537  if (i < 0 || i >= n)
1538  return ERROR_INT("invalid index into daa", __func__, 1);
1539  da = daa->dna[i];
1540  if (j < 0 || j >= da->n)
1541  return ERROR_INT("invalid index into da", __func__, 1);
1542  *pval = da->array[j];
1543  return 0;
1544 }
1545 
1546 
1560 l_ok
1562  l_int32 index,
1563  l_float64 val)
1564 {
1565 l_int32 n;
1566 L_DNA *da;
1567 
1568  if (!daa)
1569  return ERROR_INT("daa not defined", __func__, 1);
1570  n = l_dnaaGetCount(daa);
1571  if (index < 0 || index >= n)
1572  return ERROR_INT("invalid index in daa", __func__, 1);
1573 
1574  da = l_dnaaGetDna(daa, index, L_CLONE);
1575  l_dnaAddNumber(da, val);
1576  l_dnaDestroy(&da);
1577  return 0;
1578 }
1579 
1580 
1581 /*----------------------------------------------------------------------*
1582  * Serialize Dna for I/O *
1583  *----------------------------------------------------------------------*/
1590 L_DNAA *
1591 l_dnaaRead(const char *filename)
1592 {
1593 FILE *fp;
1594 L_DNAA *daa;
1595 
1596  if (!filename)
1597  return (L_DNAA *)ERROR_PTR("filename not defined", __func__, NULL);
1598 
1599  if ((fp = fopenReadStream(filename)) == NULL)
1600  return (L_DNAA *)ERROR_PTR("stream not opened", __func__, NULL);
1601  daa = l_dnaaReadStream(fp);
1602  fclose(fp);
1603  if (!daa)
1604  return (L_DNAA *)ERROR_PTR("daa not read", __func__, NULL);
1605  return daa;
1606 }
1607 
1608 
1620 L_DNAA *
1622 {
1623 l_int32 i, n, index, ret, version;
1624 L_DNA *da;
1625 L_DNAA *daa;
1626 
1627  if (!fp)
1628  return (L_DNAA *)ERROR_PTR("stream not defined", __func__, NULL);
1629 
1630  ret = fscanf(fp, "\nL_Dnaa Version %d\n", &version);
1631  if (ret != 1)
1632  return (L_DNAA *)ERROR_PTR("not a l_dna file", __func__, NULL);
1633  if (version != DNA_VERSION_NUMBER)
1634  return (L_DNAA *)ERROR_PTR("invalid l_dnaa version", __func__, NULL);
1635  if (fscanf(fp, "Number of L_Dna = %d\n\n", &n) != 1)
1636  return (L_DNAA *)ERROR_PTR("invalid number of l_dna", __func__, NULL);
1637  if (n < 0)
1638  return (L_DNAA *)ERROR_PTR("num l_dna <= 0", __func__, NULL);
1639  if (n > MaxPtrArraySize)
1640  return (L_DNAA *)ERROR_PTR("too many l_dna", __func__, NULL);
1641  if (n == 0) L_INFO("the dnaa is empty\n", __func__);
1642 
1643  if ((daa = l_dnaaCreate(n)) == NULL)
1644  return (L_DNAA *)ERROR_PTR("daa not made", __func__, NULL);
1645  for (i = 0; i < n; i++) {
1646  if (fscanf(fp, "L_Dna[%d]:", &index) != 1) {
1647  l_dnaaDestroy(&daa);
1648  return (L_DNAA *)ERROR_PTR("invalid l_dna header", __func__, NULL);
1649  }
1650  if ((da = l_dnaReadStream(fp)) == NULL) {
1651  l_dnaaDestroy(&daa);
1652  return (L_DNAA *)ERROR_PTR("da not made", __func__, NULL);
1653  }
1654  l_dnaaAddDna(daa, da, L_INSERT);
1655  }
1656 
1657  return daa;
1658 }
1659 
1660 
1668 L_DNAA *
1669 l_dnaaReadMem(const l_uint8 *data,
1670  size_t size)
1671 {
1672 FILE *fp;
1673 L_DNAA *daa;
1674 
1675  if (!data)
1676  return (L_DNAA *)ERROR_PTR("data not defined", __func__, NULL);
1677  if ((fp = fopenReadFromMemory(data, size)) == NULL)
1678  return (L_DNAA *)ERROR_PTR("stream not opened", __func__, NULL);
1679 
1680  daa = l_dnaaReadStream(fp);
1681  fclose(fp);
1682  if (!daa) L_ERROR("daa not read\n", __func__);
1683  return daa;
1684 }
1685 
1686 
1694 l_ok
1695 l_dnaaWrite(const char *filename,
1696  L_DNAA *daa)
1697 {
1698 l_int32 ret;
1699 FILE *fp;
1700 
1701  if (!filename)
1702  return ERROR_INT("filename not defined", __func__, 1);
1703  if (!daa)
1704  return ERROR_INT("daa not defined", __func__, 1);
1705 
1706  if ((fp = fopenWriteStream(filename, "w")) == NULL)
1707  return ERROR_INT("stream not opened", __func__, 1);
1708  ret = l_dnaaWriteStream(fp, daa);
1709  fclose(fp);
1710  if (ret)
1711  return ERROR_INT("daa not written to stream", __func__, 1);
1712  return 0;
1713 }
1714 
1715 
1723 l_ok
1725  L_DNAA *daa)
1726 {
1727 l_int32 i, n;
1728 L_DNA *da;
1729 
1730  if (!fp)
1731  return ERROR_INT("stream not defined", __func__, 1);
1732  if (!daa)
1733  return ERROR_INT("daa not defined", __func__, 1);
1734 
1735  n = l_dnaaGetCount(daa);
1736  fprintf(fp, "\nL_Dnaa Version %d\n", DNA_VERSION_NUMBER);
1737  fprintf(fp, "Number of L_Dna = %d\n\n", n);
1738  for (i = 0; i < n; i++) {
1739  if ((da = l_dnaaGetDna(daa, i, L_CLONE)) == NULL)
1740  return ERROR_INT("da not found", __func__, 1);
1741  fprintf(fp, "L_Dna[%d]:", i);
1742  l_dnaWriteStream(fp, da);
1743  l_dnaDestroy(&da);
1744  }
1745 
1746  return 0;
1747 }
1748 
1749 
1763 l_ok
1764 l_dnaaWriteMem(l_uint8 **pdata,
1765  size_t *psize,
1766  L_DNAA *daa)
1767 {
1768 l_int32 ret;
1769 FILE *fp;
1770 
1771  if (pdata) *pdata = NULL;
1772  if (psize) *psize = 0;
1773  if (!pdata)
1774  return ERROR_INT("&data not defined", __func__, 1);
1775  if (!psize)
1776  return ERROR_INT("&size not defined", __func__, 1);
1777  if (!daa)
1778  return ERROR_INT("daa not defined", __func__, 1);
1779 
1780 #if HAVE_FMEMOPEN
1781  if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1782  return ERROR_INT("stream not opened", __func__, 1);
1783  ret = l_dnaaWriteStream(fp, daa);
1784  fputc('\0', fp);
1785  fclose(fp);
1786  *psize = *psize - 1;
1787 #else
1788  L_INFO("work-around: writing to a temp file\n", __func__);
1789  #ifdef _WIN32
1790  if ((fp = fopenWriteWinTempfile()) == NULL)
1791  return ERROR_INT("tmpfile stream not opened", __func__, 1);
1792  #else
1793  if ((fp = tmpfile()) == NULL)
1794  return ERROR_INT("tmpfile stream not opened", __func__, 1);
1795  #endif /* _WIN32 */
1796  ret = l_dnaaWriteStream(fp, daa);
1797  rewind(fp);
1798  *pdata = l_binaryReadStream(fp, psize);
1799  fclose(fp);
1800 #endif /* HAVE_FMEMOPEN */
1801  return ret;
1802 }
1803 
#define DNA_VERSION_NUMBER
L_DNAA * l_dnaaRead(const char *filename)
l_dnaaRead()
Definition: dnabasic.c:1591
L_DNA * l_dnaReadStream(FILE *fp)
l_dnaReadStream()
Definition: dnabasic.c:958
l_ok l_dnaWriteStream(FILE *fp, L_DNA *da)
l_dnaWriteStream()
Definition: dnabasic.c:1060
l_ok l_dnaaReplaceDna(L_DNAA *daa, l_int32 index, L_DNA *da)
l_dnaaReplaceDna()
Definition: dnabasic.c:1493
L_DNA * l_dnaCreate(l_int32 n)
l_dnaCreate()
Definition: dnabasic.c:179
l_int32 l_dnaaGetCount(L_DNAA *daa)
l_dnaaGetCount()
Definition: dnabasic.c:1396
l_int32 l_dnaaGetDnaCount(L_DNAA *daa, l_int32 index)
l_dnaaGetDnaCount()
Definition: dnabasic.c:1412
L_DNAA * l_dnaaReadMem(const l_uint8 *data, size_t size)
l_dnaaReadMem()
Definition: dnabasic.c:1669
L_DNAA * l_dnaaCreateFull(l_int32 nptr, l_int32 n)
l_dnaaCreateFull()
Definition: dnabasic.c:1218
l_ok l_dnaGetIValue(L_DNA *da, l_int32 index, l_int32 *pival)
l_dnaGetIValue()
Definition: dnabasic.c:693
L_DNAA * l_dnaaReadStream(FILE *fp)
l_dnaaReadStream()
Definition: dnabasic.c:1621
l_ok l_dnaAddNumber(L_DNA *da, l_float64 val)
l_dnaAddNumber()
Definition: dnabasic.c:430
l_ok l_dnaCopyParameters(L_DNA *dad, L_DNA *das)
l_dnaCopyParameters()
Definition: dnabasic.c:903
l_ok l_dnaaTruncate(L_DNAA *daa)
l_dnaaTruncate()
Definition: dnabasic.c:1249
L_DNA * l_dnaRead(const char *filename)
l_dnaRead()
Definition: dnabasic.c:927
L_DNA * l_dnaMakeSequence(l_float64 startval, l_float64 increment, l_int32 size)
l_dnaMakeSequence()
Definition: dnabasic.c:290
l_ok l_dnaSetValue(L_DNA *da, l_int32 index, l_float64 val)
l_dnaSetValue()
Definition: dnabasic.c:723
static l_int32 l_dnaaExtendArray(L_DNAA *daa)
l_dnaaExtendArray()
Definition: dnabasic.c:1364
L_DNA * l_dnaCreateFromIArray(l_int32 *iarray, l_int32 size)
l_dnaCreateFromIArray()
Definition: dnabasic.c:218
L_DNA * l_dnaaGetDna(L_DNAA *daa, l_int32 index, l_int32 accessflag)
l_dnaaGetDna()
Definition: dnabasic.c:1459
l_ok l_dnaaAddNumber(L_DNAA *daa, l_int32 index, l_float64 val)
l_dnaaAddNumber()
Definition: dnabasic.c:1561
static l_int32 l_dnaExtendArray(L_DNA *da)
l_dnaExtendArray()
Definition: dnabasic.c:462
l_ok l_dnaaWriteStream(FILE *fp, L_DNAA *daa)
l_dnaaWriteStream()
Definition: dnabasic.c:1724
l_ok l_dnaShiftValue(L_DNA *da, l_int32 index, l_float64 diff)
l_dnaShiftValue()
Definition: dnabasic.c:746
l_ok l_dnaRemoveNumber(L_DNA *da, l_int32 index)
l_dnaRemoveNumber()
Definition: dnabasic.c:545
l_ok l_dnaEmpty(L_DNA *da)
l_dnaEmpty()
Definition: dnabasic.c:408
l_float64 * l_dnaGetDArray(L_DNA *da, l_int32 copyflag)
l_dnaGetDArray()
Definition: dnabasic.c:822
L_DNAA * l_dnaaCreate(l_int32 n)
l_dnaaCreate()
Definition: dnabasic.c:1184
l_ok l_dnaSetParameters(L_DNA *da, l_float64 startx, l_float64 delx)
l_dnaSetParameters()
Definition: dnabasic.c:882
l_ok l_dnaaWrite(const char *filename, L_DNAA *daa)
l_dnaaWrite()
Definition: dnabasic.c:1695
l_ok l_dnaGetDValue(L_DNA *da, l_int32 index, l_float64 *pval)
l_dnaGetDValue()
Definition: dnabasic.c:660
static const l_int32 InitialArraySize
Definition: dnabasic.c:163
l_ok l_dnaaWriteMem(l_uint8 **pdata, size_t *psize, L_DNAA *daa)
l_dnaaWriteMem()
Definition: dnabasic.c:1764
L_DNA * l_dnaCreateFromDArray(l_float64 *darray, l_int32 size, l_int32 copyflag)
l_dnaCreateFromDArray()
Definition: dnabasic.c:253
l_ok l_dnaInsertNumber(L_DNA *da, l_int32 index, l_float64 val)
l_dnaInsertNumber()
Definition: dnabasic.c:504
l_int32 l_dnaaGetNumberCount(L_DNAA *daa)
l_dnaaGetNumberCount()
Definition: dnabasic.c:1431
L_DNA * l_dnaClone(L_DNA *da)
l_dnaClone()
Definition: dnabasic.c:384
l_ok l_dnaSetCount(L_DNA *da, l_int32 newcount)
l_dnaSetCount()
Definition: dnabasic.c:628
l_ok l_dnaaAddDna(L_DNAA *daa, L_DNA *da, l_int32 copyflag)
l_dnaaAddDna()
Definition: dnabasic.c:1314
l_ok l_dnaaGetValue(L_DNAA *daa, l_int32 i, l_int32 j, l_float64 *pval)
l_dnaaGetValue()
Definition: dnabasic.c:1523
l_ok l_dnaWriteStderr(L_DNA *da)
l_dnaWriteStrderr()
Definition: dnabasic.c:1094
l_ok l_dnaReplaceNumber(L_DNA *da, l_int32 index, l_float64 val)
l_dnaReplaceNumber()
Definition: dnabasic.c:574
void l_dnaDestroy(L_DNA **pda)
l_dnaDestroy()
Definition: dnabasic.c:323
l_ok l_dnaGetParameters(L_DNA *da, l_float64 *pstartx, l_float64 *pdelx)
l_dnaGetParameters()
Definition: dnabasic.c:854
l_ok l_dnaWriteMem(l_uint8 **pdata, size_t *psize, L_DNA *da)
l_dnaWriteMem()
Definition: dnabasic.c:1132
l_ok l_dnaWrite(const char *filename, L_DNA *da)
l_dnaWrite()
Definition: dnabasic.c:1031
l_int32 * l_dnaGetIArray(L_DNA *da)
l_dnaGetIArray()
Definition: dnabasic.c:780
L_DNA * l_dnaCopy(L_DNA *da)
l_dnaCopy()
Definition: dnabasic.c:357
l_int32 l_dnaGetCount(L_DNA *da)
l_dnaGetCount()
Definition: dnabasic.c:603
L_DNA * l_dnaReadMem(const l_uint8 *data, size_t size)
l_dnaReadMem()
Definition: dnabasic.c:1005
void l_dnaaDestroy(L_DNAA **pdaa)
l_dnaaDestroy()
Definition: dnabasic.c:1281
@ 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_float64 startx
l_int32 n
l_atomic refcount
l_float64 * array
l_int32 nalloc
l_float64 delx
l_int32 n
l_int32 nalloc
struct L_Dna ** dna
void lept_stderr(const char *fmt,...)
lept_stderr()
Definition: utils1.c:306
l_uint8 * l_binaryReadStream(FILE *fp, size_t *pnbytes)
l_binaryReadStream()
Definition: utils2.c:1358
FILE * fopenReadFromMemory(const l_uint8 *data, size_t size)
fopenReadFromMemory()
Definition: utils2.c:1937
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1905
void * reallocNew(void **pindata, size_t oldsize, size_t newsize)
reallocNew()
Definition: utils2.c:1262
FILE * fopenWriteWinTempfile(void)
fopenWriteWinTempfile()
Definition: utils2.c:1981
FILE * fopenReadStream(const char *filename)
fopenReadStream()
Definition: utils2.c:1864