Leptonica 1.85.0
Image processing and image analysis suite
Loading...
Searching...
No Matches
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 */
161static const l_uint32 MaxDoubleArraySize = 100000000; /* for dna */
162static const l_uint32 MaxPtrArraySize = 1000000; /* for dnaa */
163static const l_int32 InitialArraySize = 50;
165 /* Static functions */
166static l_int32 l_dnaExtendArray(L_DNA *da);
167static l_int32 l_dnaaExtendArray(L_DNAA *daa);
168
169/*--------------------------------------------------------------------------*
170 * Dna creation, destruction, copy, clone, etc. *
171 *--------------------------------------------------------------------------*/
178L_DNA *
179l_dnaCreate(l_int32 n)
180{
181L_DNA *da;
182
183 if (n <= 0 || n > MaxDoubleArraySize)
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
217L_DNA *
218l_dnaCreateFromIArray(l_int32 *iarray,
219 l_int32 size)
220{
221l_int32 i;
222L_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
252L_DNA *
253l_dnaCreateFromDArray(l_float64 *darray,
254 l_int32 size,
255 l_int32 copyflag)
256{
257l_int32 i;
258L_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
289L_DNA *
290l_dnaMakeSequence(l_float64 startval,
291 l_float64 increment,
292 l_int32 size)
293{
294l_int32 i;
295l_float64 val;
296L_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
322void
324{
325L_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
356L_DNA *
358{
359l_int32 i;
360L_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
383L_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
407l_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 *--------------------------------------------------------------------------*/
429l_ok
431 l_float64 val)
432{
433l_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
461static l_int32
463{
464size_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
503l_ok
505 l_int32 index,
506 l_float64 val)
507{
508l_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
544l_ok
546 l_int32 index)
547{
548l_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
573l_ok
575 l_int32 index,
576 l_float64 val)
577{
578l_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 *----------------------------------------------------------------------*/
602l_int32
604{
605 if (!da)
606 return ERROR_INT("da not defined", __func__, 0);
607 return da->n;
608}
609
610
627l_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
659l_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
692l_ok
694 l_int32 index,
695 l_int32 *pival)
696{
697l_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
722l_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
745l_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
779l_int32 *
781{
782l_int32 i, n, ival;
783l_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
821l_float64 *
823 l_int32 copyflag)
824{
825l_int32 i, n;
826l_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
853l_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
881l_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
902l_ok
904 L_DNA *das)
905{
906l_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 *----------------------------------------------------------------------*/
926L_DNA *
927l_dnaRead(const char *filename)
928{
929FILE *fp;
930L_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_1("stream not opened",
937 filename, __func__, NULL);
938 da = l_dnaReadStream(fp);
939 fclose(fp);
940 if (!da)
941 return (L_DNA *)ERROR_PTR_1("da not read",
942 filename, __func__, NULL);
943 return da;
944}
945
946
959L_DNA *
961{
962l_int32 i, n, index, ret, version;
963l_float64 val, startx, delx;
964L_DNA *da;
965
966 if (!fp)
967 return (L_DNA *)ERROR_PTR("stream not defined", __func__, NULL);
968
969 ret = fscanf(fp, "\nL_Dna Version %d\n", &version);
970 if (ret != 1)
971 return (L_DNA *)ERROR_PTR("not a l_dna file", __func__, NULL);
972 if (version != DNA_VERSION_NUMBER)
973 return (L_DNA *)ERROR_PTR("invalid l_dna version", __func__, NULL);
974 if (fscanf(fp, "Number of numbers = %d\n", &n) != 1)
975 return (L_DNA *)ERROR_PTR("invalid number of numbers", __func__, NULL);
976 if (n < 0)
977 return (L_DNA *)ERROR_PTR("num doubles < 0", __func__, NULL);
978 if (n > MaxDoubleArraySize)
979 return (L_DNA *)ERROR_PTR("too many doubles", __func__, NULL);
980 if (n == 0) L_INFO("the dna is empty\n", __func__);
981
982 if ((da = l_dnaCreate(n)) == NULL)
983 return (L_DNA *)ERROR_PTR("da not made", __func__, NULL);
984 for (i = 0; i < n; i++) {
985 if (fscanf(fp, " [%d] = %lf\n", &index, &val) != 2) {
986 l_dnaDestroy(&da);
987 return (L_DNA *)ERROR_PTR("bad input data", __func__, NULL);
988 }
989 l_dnaAddNumber(da, val);
990 }
991
992 /* Optional data */
993 if (fscanf(fp, "startx = %lf, delx = %lf\n", &startx, &delx) == 2)
994 l_dnaSetParameters(da, startx, delx);
995 return da;
996}
997
998
1006L_DNA *
1007l_dnaReadMem(const l_uint8 *data,
1008 size_t size)
1009{
1010FILE *fp;
1011L_DNA *da;
1012
1013 if (!data)
1014 return (L_DNA *)ERROR_PTR("data not defined", __func__, NULL);
1015 if ((fp = fopenReadFromMemory(data, size)) == NULL)
1016 return (L_DNA *)ERROR_PTR("stream not opened", __func__, NULL);
1017
1018 da = l_dnaReadStream(fp);
1019 fclose(fp);
1020 if (!da) L_ERROR("dna not read\n", __func__);
1021 return da;
1022}
1023
1024
1032l_ok
1033l_dnaWrite(const char *filename,
1034 L_DNA *da)
1035{
1036l_int32 ret;
1037FILE *fp;
1038
1039 if (!filename)
1040 return ERROR_INT("filename not defined", __func__, 1);
1041 if (!da)
1042 return ERROR_INT("da not defined", __func__, 1);
1043
1044 if ((fp = fopenWriteStream(filename, "w")) == NULL)
1045 return ERROR_INT_1("stream not opened", filename, __func__, 1);
1046 ret = l_dnaWriteStream(fp, da);
1047 fclose(fp);
1048 if (ret)
1049 return ERROR_INT_1("da not written to stream", filename, __func__, 1);
1050 return 0;
1051}
1052
1053
1061l_ok
1063 L_DNA *da)
1064{
1065l_int32 i, n;
1066l_float64 startx, delx;
1067
1068 if (!da)
1069 return ERROR_INT("da not defined", __func__, 1);
1070 if (!fp)
1071 return l_dnaWriteStderr(da);
1072
1073 n = l_dnaGetCount(da);
1074 fprintf(fp, "\nL_Dna Version %d\n", DNA_VERSION_NUMBER);
1075 fprintf(fp, "Number of numbers = %d\n", n);
1076 for (i = 0; i < n; i++)
1077 fprintf(fp, " [%d] = %f\n", i, da->array[i]);
1078 fprintf(fp, "\n");
1079
1080 /* Optional data */
1081 l_dnaGetParameters(da, &startx, &delx);
1082 if (startx != 0.0 || delx != 1.0)
1083 fprintf(fp, "startx = %f, delx = %f\n", startx, delx);
1084
1085 return 0;
1086}
1087
1088
1095l_ok
1097{
1098l_int32 i, n;
1099l_float64 startx, delx;
1100
1101 if (!da)
1102 return ERROR_INT("da not defined", __func__, 1);
1103
1104 n = l_dnaGetCount(da);
1105 lept_stderr("\nL_Dna Version %d\n", DNA_VERSION_NUMBER);
1106 lept_stderr("Number of numbers = %d\n", n);
1107 for (i = 0; i < n; i++)
1108 lept_stderr(" [%d] = %f\n", i, da->array[i]);
1109 lept_stderr("\n");
1110
1111 /* Optional data */
1112 l_dnaGetParameters(da, &startx, &delx);
1113 if (startx != 0.0 || delx != 1.0)
1114 lept_stderr("startx = %f, delx = %f\n", startx, delx);
1115
1116 return 0;
1117}
1118
1119
1133l_ok
1134l_dnaWriteMem(l_uint8 **pdata,
1135 size_t *psize,
1136 L_DNA *da)
1137{
1138l_int32 ret;
1139FILE *fp;
1140
1141 if (pdata) *pdata = NULL;
1142 if (psize) *psize = 0;
1143 if (!pdata)
1144 return ERROR_INT("&data not defined", __func__, 1);
1145 if (!psize)
1146 return ERROR_INT("&size not defined", __func__, 1);
1147 if (!da)
1148 return ERROR_INT("da not defined", __func__, 1);
1149
1150#if HAVE_FMEMOPEN
1151 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1152 return ERROR_INT("stream not opened", __func__, 1);
1153 ret = l_dnaWriteStream(fp, da);
1154 fputc('\0', fp);
1155 fclose(fp);
1156 if (*psize > 0) *psize = *psize - 1;
1157#else
1158 L_INFO("no fmemopen API --> work-around: write to temp file\n", __func__);
1159 #ifdef _WIN32
1160 if ((fp = fopenWriteWinTempfile()) == NULL)
1161 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1162 #else
1163 if ((fp = tmpfile()) == NULL)
1164 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1165 #endif /* _WIN32 */
1166 ret = l_dnaWriteStream(fp, da);
1167 rewind(fp);
1168 *pdata = l_binaryReadStream(fp, psize);
1169 fclose(fp);
1170#endif /* HAVE_FMEMOPEN */
1171 return ret;
1172}
1173
1174
1175/*--------------------------------------------------------------------------*
1176 * Dnaa creation, destruction *
1177 *--------------------------------------------------------------------------*/
1185L_DNAA *
1187{
1188L_DNAA *daa;
1189
1190 if (n <= 0 || n > MaxPtrArraySize)
1191 n = InitialArraySize;
1192
1193 daa = (L_DNAA *)LEPT_CALLOC(1, sizeof(L_DNAA));
1194 if ((daa->dna = (L_DNA **)LEPT_CALLOC(n, sizeof(L_DNA *))) == NULL) {
1195 l_dnaaDestroy(&daa);
1196 return (L_DNAA *)ERROR_PTR("l_dna ptr array not made", __func__, NULL);
1197 }
1198 daa->nalloc = n;
1199 daa->n = 0;
1200 return daa;
1201}
1202
1203
1219L_DNAA *
1220l_dnaaCreateFull(l_int32 nptr,
1221 l_int32 n)
1222{
1223l_int32 i;
1224L_DNAA *daa;
1225L_DNA *da;
1226
1227 daa = l_dnaaCreate(nptr);
1228 for (i = 0; i < nptr; i++) {
1229 da = l_dnaCreate(n);
1230 l_dnaaAddDna(daa, da, L_INSERT);
1231 }
1232
1233 return daa;
1234}
1235
1236
1250l_ok
1252{
1253l_int32 i, n, nn;
1254L_DNA *da;
1255
1256 if (!daa)
1257 return ERROR_INT("daa not defined", __func__, 1);
1258
1259 n = l_dnaaGetCount(daa);
1260 for (i = n - 1; i >= 0; i--) {
1261 da = l_dnaaGetDna(daa, i, L_CLONE);
1262 if (!da)
1263 continue;
1264 nn = l_dnaGetCount(da);
1265 l_dnaDestroy(&da); /* the clone */
1266 if (nn == 0)
1267 l_dnaDestroy(&daa->dna[i]);
1268 else
1269 break;
1270 }
1271 daa->n = i + 1;
1272 return 0;
1273}
1274
1275
1282void
1284{
1285l_int32 i;
1286L_DNAA *daa;
1287
1288 if (pdaa == NULL) {
1289 L_WARNING("ptr address is NULL!\n", __func__);
1290 return;
1291 }
1292
1293 if ((daa = *pdaa) == NULL)
1294 return;
1295
1296 for (i = 0; i < daa->n; i++)
1297 l_dnaDestroy(&daa->dna[i]);
1298 LEPT_FREE(daa->dna);
1299 LEPT_FREE(daa);
1300 *pdaa = NULL;
1301}
1302
1303
1304/*--------------------------------------------------------------------------*
1305 * Add Dna to Dnaa *
1306 *--------------------------------------------------------------------------*/
1315l_ok
1317 L_DNA *da,
1318 l_int32 copyflag)
1319{
1320l_int32 n;
1321L_DNA *dac;
1322
1323 if (!daa)
1324 return ERROR_INT("daa not defined", __func__, 1);
1325 if (!da)
1326 return ERROR_INT("da not defined", __func__, 1);
1327
1328 if (copyflag == L_INSERT) {
1329 dac = da;
1330 } else if (copyflag == L_COPY) {
1331 if ((dac = l_dnaCopy(da)) == NULL)
1332 return ERROR_INT("dac not made", __func__, 1);
1333 } else if (copyflag == L_CLONE) {
1334 dac = l_dnaClone(da);
1335 } else {
1336 return ERROR_INT("invalid copyflag", __func__, 1);
1337 }
1338
1339 n = l_dnaaGetCount(daa);
1340 if (n >= daa->nalloc) {
1341 if (l_dnaaExtendArray(daa)) {
1342 if (copyflag != L_INSERT)
1343 l_dnaDestroy(&dac);
1344 return ERROR_INT("extension failed", __func__, 1);
1345 }
1346 }
1347 daa->dna[n] = dac;
1348 daa->n++;
1349 return 0;
1350}
1351
1352
1365static l_int32
1367{
1368size_t oldsize, newsize;
1369
1370 if (!daa)
1371 return ERROR_INT("daa not defined", __func__, 1);
1372 if (daa->nalloc > MaxPtrArraySize) /* belt & suspenders */
1373 return ERROR_INT("daa has too many ptrs", __func__, 1);
1374 oldsize = daa->nalloc * sizeof(L_DNA *);
1375 newsize = 2 * oldsize;
1376 if (newsize > 8 * MaxPtrArraySize)
1377 return ERROR_INT("newsize > 8 MB; too large", __func__, 1);
1378
1379 if ((daa->dna = (L_DNA **)reallocNew((void **)&daa->dna,
1380 oldsize, newsize)) == NULL)
1381 return ERROR_INT("new ptr array not returned", __func__, 1);
1382
1383 daa->nalloc *= 2;
1384 return 0;
1385}
1386
1387
1388/*----------------------------------------------------------------------*
1389 * DNumaa accessors *
1390 *----------------------------------------------------------------------*/
1397l_int32
1399{
1400 if (!daa)
1401 return ERROR_INT("daa not defined", __func__, 0);
1402 return daa->n;
1403}
1404
1405
1413l_int32
1415 l_int32 index)
1416{
1417 if (!daa)
1418 return ERROR_INT("daa not defined", __func__, 0);
1419 if (index < 0 || index >= daa->n)
1420 return ERROR_INT("invalid index into daa", __func__, 0);
1421 return l_dnaGetCount(daa->dna[index]);
1422}
1423
1424
1432l_int32
1434{
1435L_DNA *da;
1436l_int32 n, sum, i;
1437
1438 if (!daa)
1439 return ERROR_INT("daa not defined", __func__, 0);
1440
1441 n = l_dnaaGetCount(daa);
1442 for (sum = 0, i = 0; i < n; i++) {
1443 da = l_dnaaGetDna(daa, i, L_CLONE);
1444 sum += l_dnaGetCount(da);
1445 l_dnaDestroy(&da);
1446 }
1447
1448 return sum;
1449}
1450
1451
1460L_DNA *
1462 l_int32 index,
1463 l_int32 accessflag)
1464{
1465 if (!daa)
1466 return (L_DNA *)ERROR_PTR("daa not defined", __func__, NULL);
1467 if (index < 0 || index >= daa->n)
1468 return (L_DNA *)ERROR_PTR("index not valid", __func__, NULL);
1469
1470 if (accessflag == L_COPY)
1471 return l_dnaCopy(daa->dna[index]);
1472 else if (accessflag == L_CLONE)
1473 return l_dnaClone(daa->dna[index]);
1474 else
1475 return (L_DNA *)ERROR_PTR("invalid accessflag", __func__, NULL);
1476}
1477
1478
1494l_ok
1496 l_int32 index,
1497 L_DNA *da)
1498{
1499l_int32 n;
1500
1501 if (!daa)
1502 return ERROR_INT("daa not defined", __func__, 1);
1503 if (!da)
1504 return ERROR_INT("da not defined", __func__, 1);
1505 n = l_dnaaGetCount(daa);
1506 if (index < 0 || index >= n)
1507 return ERROR_INT("index not valid", __func__, 1);
1508
1509 l_dnaDestroy(&daa->dna[index]);
1510 daa->dna[index] = da;
1511 return 0;
1512}
1513
1514
1524l_ok
1526 l_int32 i,
1527 l_int32 j,
1528 l_float64 *pval)
1529{
1530l_int32 n;
1531L_DNA *da;
1532
1533 if (!pval)
1534 return ERROR_INT("&val not defined", __func__, 1);
1535 *pval = 0.0;
1536 if (!daa)
1537 return ERROR_INT("daa not defined", __func__, 1);
1538 n = l_dnaaGetCount(daa);
1539 if (i < 0 || i >= n)
1540 return ERROR_INT("invalid index into daa", __func__, 1);
1541 da = daa->dna[i];
1542 if (j < 0 || j >= da->n)
1543 return ERROR_INT("invalid index into da", __func__, 1);
1544 *pval = da->array[j];
1545 return 0;
1546}
1547
1548
1562l_ok
1564 l_int32 index,
1565 l_float64 val)
1566{
1567l_int32 n;
1568L_DNA *da;
1569
1570 if (!daa)
1571 return ERROR_INT("daa not defined", __func__, 1);
1572 n = l_dnaaGetCount(daa);
1573 if (index < 0 || index >= n)
1574 return ERROR_INT("invalid index in daa", __func__, 1);
1575
1576 da = l_dnaaGetDna(daa, index, L_CLONE);
1577 l_dnaAddNumber(da, val);
1578 l_dnaDestroy(&da);
1579 return 0;
1580}
1581
1582
1583/*----------------------------------------------------------------------*
1584 * Serialize Dna for I/O *
1585 *----------------------------------------------------------------------*/
1592L_DNAA *
1593l_dnaaRead(const char *filename)
1594{
1595FILE *fp;
1596L_DNAA *daa;
1597
1598 if (!filename)
1599 return (L_DNAA *)ERROR_PTR("filename not defined", __func__, NULL);
1600
1601 if ((fp = fopenReadStream(filename)) == NULL)
1602 return (L_DNAA *)ERROR_PTR_1("stream not opened",
1603 filename, __func__, NULL);
1604 daa = l_dnaaReadStream(fp);
1605 fclose(fp);
1606 if (!daa)
1607 return (L_DNAA *)ERROR_PTR_1("daa not read",
1608 filename, __func__, NULL);
1609 return daa;
1610}
1611
1612
1624L_DNAA *
1626{
1627l_int32 i, n, index, ret, version;
1628L_DNA *da;
1629L_DNAA *daa;
1630
1631 if (!fp)
1632 return (L_DNAA *)ERROR_PTR("stream not defined", __func__, NULL);
1633
1634 ret = fscanf(fp, "\nL_Dnaa Version %d\n", &version);
1635 if (ret != 1)
1636 return (L_DNAA *)ERROR_PTR("not a l_dna file", __func__, NULL);
1637 if (version != DNA_VERSION_NUMBER)
1638 return (L_DNAA *)ERROR_PTR("invalid l_dnaa version", __func__, NULL);
1639 if (fscanf(fp, "Number of L_Dna = %d\n\n", &n) != 1)
1640 return (L_DNAA *)ERROR_PTR("invalid number of l_dna", __func__, NULL);
1641 if (n < 0)
1642 return (L_DNAA *)ERROR_PTR("num l_dna <= 0", __func__, NULL);
1643 if (n > MaxPtrArraySize)
1644 return (L_DNAA *)ERROR_PTR("too many l_dna", __func__, NULL);
1645 if (n == 0) L_INFO("the dnaa is empty\n", __func__);
1646
1647 if ((daa = l_dnaaCreate(n)) == NULL)
1648 return (L_DNAA *)ERROR_PTR("daa not made", __func__, NULL);
1649 for (i = 0; i < n; i++) {
1650 if (fscanf(fp, "L_Dna[%d]:", &index) != 1) {
1651 l_dnaaDestroy(&daa);
1652 return (L_DNAA *)ERROR_PTR("invalid l_dna header", __func__, NULL);
1653 }
1654 if ((da = l_dnaReadStream(fp)) == NULL) {
1655 l_dnaaDestroy(&daa);
1656 return (L_DNAA *)ERROR_PTR("da not made", __func__, NULL);
1657 }
1658 l_dnaaAddDna(daa, da, L_INSERT);
1659 }
1660
1661 return daa;
1662}
1663
1664
1672L_DNAA *
1673l_dnaaReadMem(const l_uint8 *data,
1674 size_t size)
1675{
1676FILE *fp;
1677L_DNAA *daa;
1678
1679 if (!data)
1680 return (L_DNAA *)ERROR_PTR("data not defined", __func__, NULL);
1681 if ((fp = fopenReadFromMemory(data, size)) == NULL)
1682 return (L_DNAA *)ERROR_PTR("stream not opened", __func__, NULL);
1683
1684 daa = l_dnaaReadStream(fp);
1685 fclose(fp);
1686 if (!daa) L_ERROR("daa not read\n", __func__);
1687 return daa;
1688}
1689
1690
1698l_ok
1699l_dnaaWrite(const char *filename,
1700 L_DNAA *daa)
1701{
1702l_int32 ret;
1703FILE *fp;
1704
1705 if (!filename)
1706 return ERROR_INT("filename not defined", __func__, 1);
1707 if (!daa)
1708 return ERROR_INT("daa not defined", __func__, 1);
1709
1710 if ((fp = fopenWriteStream(filename, "w")) == NULL)
1711 return ERROR_INT_1("stream not opened", filename, __func__, 1);
1712 ret = l_dnaaWriteStream(fp, daa);
1713 fclose(fp);
1714 if (ret)
1715 return ERROR_INT_1("daa not written to stream", filename, __func__, 1);
1716 return 0;
1717}
1718
1719
1727l_ok
1729 L_DNAA *daa)
1730{
1731l_int32 i, n;
1732L_DNA *da;
1733
1734 if (!fp)
1735 return ERROR_INT("stream not defined", __func__, 1);
1736 if (!daa)
1737 return ERROR_INT("daa not defined", __func__, 1);
1738
1739 n = l_dnaaGetCount(daa);
1740 fprintf(fp, "\nL_Dnaa Version %d\n", DNA_VERSION_NUMBER);
1741 fprintf(fp, "Number of L_Dna = %d\n\n", n);
1742 for (i = 0; i < n; i++) {
1743 if ((da = l_dnaaGetDna(daa, i, L_CLONE)) == NULL)
1744 return ERROR_INT("da not found", __func__, 1);
1745 fprintf(fp, "L_Dna[%d]:", i);
1746 l_dnaWriteStream(fp, da);
1747 l_dnaDestroy(&da);
1748 }
1749
1750 return 0;
1751}
1752
1753
1767l_ok
1768l_dnaaWriteMem(l_uint8 **pdata,
1769 size_t *psize,
1770 L_DNAA *daa)
1771{
1772l_int32 ret;
1773FILE *fp;
1774
1775 if (pdata) *pdata = NULL;
1776 if (psize) *psize = 0;
1777 if (!pdata)
1778 return ERROR_INT("&data not defined", __func__, 1);
1779 if (!psize)
1780 return ERROR_INT("&size not defined", __func__, 1);
1781 if (!daa)
1782 return ERROR_INT("daa not defined", __func__, 1);
1783
1784#if HAVE_FMEMOPEN
1785 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1786 return ERROR_INT("stream not opened", __func__, 1);
1787 ret = l_dnaaWriteStream(fp, daa);
1788 fputc('\0', fp);
1789 fclose(fp);
1790 if (*psize > 0) *psize = *psize - 1;
1791#else
1792 L_INFO("no fmemopen API --> work-around: write to temp file\n", __func__);
1793 #ifdef _WIN32
1794 if ((fp = fopenWriteWinTempfile()) == NULL)
1795 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1796 #else
1797 if ((fp = tmpfile()) == NULL)
1798 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1799 #endif /* _WIN32 */
1800 ret = l_dnaaWriteStream(fp, daa);
1801 rewind(fp);
1802 *pdata = l_binaryReadStream(fp, psize);
1803 fclose(fp);
1804#endif /* HAVE_FMEMOPEN */
1805 return ret;
1806}
1807
#define DNA_VERSION_NUMBER
L_DNA * l_dnaReadMem(const l_uint8 *data, size_t size)
l_dnaReadMem()
Definition dnabasic.c:1007
l_ok l_dnaWriteStream(FILE *fp, L_DNA *da)
l_dnaWriteStream()
Definition dnabasic.c:1062
l_ok l_dnaaReplaceDna(L_DNAA *daa, l_int32 index, L_DNA *da)
l_dnaaReplaceDna()
Definition dnabasic.c:1495
l_int32 l_dnaaGetCount(L_DNAA *daa)
l_dnaaGetCount()
Definition dnabasic.c:1398
L_DNA * l_dnaCreateFromDArray(l_float64 *darray, l_int32 size, l_int32 copyflag)
l_dnaCreateFromDArray()
Definition dnabasic.c:253
l_int32 l_dnaaGetDnaCount(L_DNAA *daa, l_int32 index)
l_dnaaGetDnaCount()
Definition dnabasic.c:1414
l_ok l_dnaGetIValue(L_DNA *da, l_int32 index, l_int32 *pival)
l_dnaGetIValue()
Definition dnabasic.c:693
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:1251
L_DNAA * l_dnaaCreate(l_int32 n)
l_dnaaCreate()
Definition dnabasic.c:1186
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:1366
l_ok l_dnaaAddNumber(L_DNAA *daa, l_int32 index, l_float64 val)
l_dnaaAddNumber()
Definition dnabasic.c:1563
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:1728
L_DNA * l_dnaClone(L_DNA *da)
l_dnaClone()
Definition dnabasic.c:384
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_DNA * l_dnaMakeSequence(l_float64 startval, l_float64 increment, l_int32 size)
l_dnaMakeSequence()
Definition dnabasic.c:290
L_DNAA * l_dnaaCreateFull(l_int32 nptr, l_int32 n)
l_dnaaCreateFull()
Definition dnabasic.c:1220
l_ok l_dnaEmpty(L_DNA *da)
l_dnaEmpty()
Definition dnabasic.c:408
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:1699
L_DNAA * l_dnaaReadStream(FILE *fp)
l_dnaaReadStream()
Definition dnabasic.c:1625
L_DNA * l_dnaCreateFromIArray(l_int32 *iarray, l_int32 size)
l_dnaCreateFromIArray()
Definition dnabasic.c:218
L_DNA * l_dnaCopy(L_DNA *da)
l_dnaCopy()
Definition dnabasic.c:357
L_DNA * l_dnaRead(const char *filename)
l_dnaRead()
Definition dnabasic.c:927
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:1768
L_DNA * l_dnaCreate(l_int32 n)
l_dnaCreate()
Definition dnabasic.c:179
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:1433
L_DNAA * l_dnaaReadMem(const l_uint8 *data, size_t size)
l_dnaaReadMem()
Definition dnabasic.c:1673
L_DNA * l_dnaReadStream(FILE *fp)
l_dnaReadStream()
Definition dnabasic.c:960
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:1316
l_int32 * l_dnaGetIArray(L_DNA *da)
l_dnaGetIArray()
Definition dnabasic.c:780
l_ok l_dnaaGetValue(L_DNAA *daa, l_int32 i, l_int32 j, l_float64 *pval)
l_dnaaGetValue()
Definition dnabasic.c:1525
l_ok l_dnaWriteStderr(L_DNA *da)
l_dnaWriteStrderr()
Definition dnabasic.c:1096
l_ok l_dnaReplaceNumber(L_DNA *da, l_int32 index, l_float64 val)
l_dnaReplaceNumber()
Definition dnabasic.c:574
l_float64 * l_dnaGetDArray(L_DNA *da, l_int32 copyflag)
l_dnaGetDArray()
Definition dnabasic.c:822
L_DNAA * l_dnaaRead(const char *filename)
l_dnaaRead()
Definition dnabasic.c:1593
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:1134
l_ok l_dnaWrite(const char *filename, L_DNA *da)
l_dnaWrite()
Definition dnabasic.c:1033
l_int32 l_dnaGetCount(L_DNA *da)
l_dnaGetCount()
Definition dnabasic.c:603
void l_dnaaDestroy(L_DNAA **pdaa)
l_dnaaDestroy()
Definition dnabasic.c:1283
L_DNA * l_dnaaGetDna(L_DNAA *daa, l_int32 index, l_int32 accessflag)
l_dnaaGetDna()
Definition dnabasic.c:1461
@ 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