Leptonica 1.82.0
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
153#ifdef HAVE_CONFIG_H
154#include <config_auto.h>
155#endif /* HAVE_CONFIG_H */
156
157#include <string.h>
158#include <math.h>
159#include "allheaders.h"
160
161 /* Bounds on initial array size */
162static const l_uint32 MaxDoubleArraySize = 100000000; /* for dna */
163static const l_uint32 MaxPtrArraySize = 1000000; /* for dnaa */
164static const l_int32 InitialArraySize = 50;
166 /* Static functions */
167static l_int32 l_dnaExtendArray(L_DNA *da);
168static l_int32 l_dnaaExtendArray(L_DNAA *daa);
169
170/*--------------------------------------------------------------------------*
171 * Dna creation, destruction, copy, clone, etc. *
172 *--------------------------------------------------------------------------*/
179L_DNA *
180l_dnaCreate(l_int32 n)
181{
182L_DNA *da;
183
184 PROCNAME("l_dnaCreate");
185
186 if (n <= 0 || n > MaxDoubleArraySize)
188
189 da = (L_DNA *)LEPT_CALLOC(1, sizeof(L_DNA));
190 if ((da->array = (l_float64 *)LEPT_CALLOC(n, sizeof(l_float64))) == NULL) {
191 l_dnaDestroy(&da);
192 return (L_DNA *)ERROR_PTR("double array not made", procName, NULL);
193 }
194
195 da->nalloc = n;
196 da->n = 0;
197 da->refcount = 1;
198 da->startx = 0.0;
199 da->delx = 1.0;
200
201 return da;
202}
203
204
220L_DNA *
221l_dnaCreateFromIArray(l_int32 *iarray,
222 l_int32 size)
223{
224l_int32 i;
225L_DNA *da;
226
227 PROCNAME("l_dnaCreateFromIArray");
228
229 if (!iarray)
230 return (L_DNA *)ERROR_PTR("iarray not defined", procName, NULL);
231 if (size <= 0)
232 return (L_DNA *)ERROR_PTR("size must be > 0", procName, NULL);
233
234 da = l_dnaCreate(size);
235 for (i = 0; i < size; i++)
236 l_dnaAddNumber(da, iarray[i]);
237
238 return da;
239}
240
241
257L_DNA *
258l_dnaCreateFromDArray(l_float64 *darray,
259 l_int32 size,
260 l_int32 copyflag)
261{
262l_int32 i;
263L_DNA *da;
264
265 PROCNAME("l_dnaCreateFromDArray");
266
267 if (!darray)
268 return (L_DNA *)ERROR_PTR("darray not defined", procName, NULL);
269 if (size <= 0)
270 return (L_DNA *)ERROR_PTR("size must be > 0", procName, NULL);
271 if (copyflag != L_INSERT && copyflag != L_COPY)
272 return (L_DNA *)ERROR_PTR("invalid copyflag", procName, NULL);
273
274 da = l_dnaCreate(size);
275 if (copyflag == L_INSERT) {
276 if (da->array) LEPT_FREE(da->array);
277 da->array = darray;
278 da->n = size;
279 } else { /* just copy the contents */
280 for (i = 0; i < size; i++)
281 l_dnaAddNumber(da, darray[i]);
282 }
283
284 return da;
285}
286
287
296L_DNA *
297l_dnaMakeSequence(l_float64 startval,
298 l_float64 increment,
299 l_int32 size)
300{
301l_int32 i;
302l_float64 val;
303L_DNA *da;
304
305 PROCNAME("l_dnaMakeSequence");
306
307 if ((da = l_dnaCreate(size)) == NULL)
308 return (L_DNA *)ERROR_PTR("da not made", procName, NULL);
309
310 for (i = 0; i < size; i++) {
311 val = startval + i * increment;
312 l_dnaAddNumber(da, val);
313 }
314
315 return da;
316}
317
318
331void
333{
334L_DNA *da;
335
336 PROCNAME("l_dnaDestroy");
337
338 if (pda == NULL) {
339 L_WARNING("ptr address is NULL\n", procName);
340 return;
341 }
342
343 if ((da = *pda) == NULL)
344 return;
345
346 /* Decrement the ref count. If it is 0, destroy the l_dna. */
347 l_dnaChangeRefcount(da, -1);
348 if (l_dnaGetRefcount(da) <= 0) {
349 if (da->array)
350 LEPT_FREE(da->array);
351 LEPT_FREE(da);
352 }
353 *pda = NULL;
354}
355
356
368L_DNA *
370{
371l_int32 i;
372L_DNA *dac;
373
374 PROCNAME("l_dnaCopy");
375
376 if (!da)
377 return (L_DNA *)ERROR_PTR("da not defined", procName, NULL);
378
379 if ((dac = l_dnaCreate(da->n)) == NULL)
380 return (L_DNA *)ERROR_PTR("dac not made", procName, NULL);
381 dac->startx = da->startx;
382 dac->delx = da->delx;
383
384 for (i = 0; i < da->n; i++)
385 l_dnaAddNumber(dac, da->array[i]);
386
387 return dac;
388}
389
390
397L_DNA *
399{
400 PROCNAME("l_dnaClone");
401
402 if (!da)
403 return (L_DNA *)ERROR_PTR("da not defined", procName, NULL);
404
405 l_dnaChangeRefcount(da, 1);
406 return da;
407}
408
409
423l_ok
425{
426 PROCNAME("l_dnaEmpty");
427
428 if (!da)
429 return ERROR_INT("da not defined", procName, 1);
430
431 da->n = 0;
432 return 0;
433}
434
435
436
437/*--------------------------------------------------------------------------*
438 * Dna: add/remove number and extend array *
439 *--------------------------------------------------------------------------*/
447l_ok
449 l_float64 val)
450{
451l_int32 n;
452
453 PROCNAME("l_dnaAddNumber");
454
455 if (!da)
456 return ERROR_INT("da not defined", procName, 1);
457
458 n = l_dnaGetCount(da);
459 if (n >= da->nalloc) {
460 if (l_dnaExtendArray(da))
461 return ERROR_INT("extension failed", procName, 1);
462 }
463 da->array[n] = val;
464 da->n++;
465 return 0;
466}
467
468
481static l_int32
483{
484size_t oldsize, newsize;
485
486 PROCNAME("l_dnaExtendArray");
487
488 if (!da)
489 return ERROR_INT("da not defined", procName, 1);
490 if (da->nalloc > MaxDoubleArraySize)
491 return ERROR_INT("da at maximum size; can't extend", procName, 1);
492 oldsize = da->nalloc * sizeof(l_float64);
493 if (da->nalloc > MaxDoubleArraySize / 2) {
494 newsize = MaxDoubleArraySize * sizeof(l_float64);
495 da->nalloc = MaxDoubleArraySize;
496 } else {
497 newsize = 2 * oldsize;
498 da->nalloc *= 2;
499 }
500 if ((da->array = (l_float64 *)reallocNew((void **)&da->array,
501 oldsize, newsize)) == NULL)
502 return ERROR_INT("new ptr array not returned", procName, 1);
503
504 return 0;
505}
506
507
525l_ok
527 l_int32 index,
528 l_float64 val)
529{
530l_int32 i, n;
531
532 PROCNAME("l_dnaInsertNumber");
533
534 if (!da)
535 return ERROR_INT("da not defined", procName, 1);
536 n = l_dnaGetCount(da);
537 if (index < 0 || index > n) {
538 L_ERROR("index %d not in [0,...,%d]\n", procName, index, n);
539 return 1;
540 }
541
542 if (n >= da->nalloc) {
543 if (l_dnaExtendArray(da))
544 return ERROR_INT("extension failed", procName, 1);
545 }
546 for (i = n; i > index; i--)
547 da->array[i] = da->array[i - 1];
548 da->array[index] = val;
549 da->n++;
550 return 0;
551}
552
553
568l_ok
570 l_int32 index)
571{
572l_int32 i, n;
573
574 PROCNAME("l_dnaRemoveNumber");
575
576 if (!da)
577 return ERROR_INT("da not defined", procName, 1);
578 n = l_dnaGetCount(da);
579 if (index < 0 || index >= n) {
580 L_ERROR("index %d not in [0,...,%d]\n", procName, index, n - 1);
581 return 1;
582 }
583
584 for (i = index + 1; i < n; i++)
585 da->array[i - 1] = da->array[i];
586 da->n--;
587 return 0;
588}
589
590
599l_ok
601 l_int32 index,
602 l_float64 val)
603{
604l_int32 n;
605
606 PROCNAME("l_dnaReplaceNumber");
607
608 if (!da)
609 return ERROR_INT("da not defined", procName, 1);
610 n = l_dnaGetCount(da);
611 if (index < 0 || index >= n) {
612 L_ERROR("index %d not in [0,...,%d]\n", procName, index, n - 1);
613 return 1;
614 }
615
616 da->array[index] = val;
617 return 0;
618}
619
620
621/*----------------------------------------------------------------------*
622 * Dna accessors *
623 *----------------------------------------------------------------------*/
630l_int32
632{
633 PROCNAME("l_dnaGetCount");
634
635 if (!da)
636 return ERROR_INT("da not defined", procName, 0);
637 return da->n;
638}
639
640
657l_ok
659 l_int32 newcount)
660{
661 PROCNAME("l_dnaSetCount");
662
663 if (!da)
664 return ERROR_INT("da not defined", procName, 1);
665 if (newcount > da->nalloc) {
666 if ((da->array = (l_float64 *)reallocNew((void **)&da->array,
667 sizeof(l_float64) * da->nalloc,
668 sizeof(l_float64) * newcount)) == NULL)
669 return ERROR_INT("new ptr array not returned", procName, 1);
670 da->nalloc = newcount;
671 }
672 da->n = newcount;
673 return 0;
674}
675
676
691l_ok
693 l_int32 index,
694 l_float64 *pval)
695{
696 PROCNAME("l_dnaGetDValue");
697
698 if (!pval)
699 return ERROR_INT("&val not defined", procName, 1);
700 *pval = 0.0;
701 if (!da)
702 return ERROR_INT("da not defined", procName, 1);
703
704 if (index < 0 || index >= da->n)
705 return ERROR_INT("index not valid", procName, 1);
706
707 *pval = da->array[index];
708 return 0;
709}
710
711
726l_ok
728 l_int32 index,
729 l_int32 *pival)
730{
731l_float64 val;
732
733 PROCNAME("l_dnaGetIValue");
734
735 if (!pival)
736 return ERROR_INT("&ival not defined", procName, 1);
737 *pival = 0;
738 if (!da)
739 return ERROR_INT("da not defined", procName, 1);
740
741 if (index < 0 || index >= da->n)
742 return ERROR_INT("index not valid", procName, 1);
743
744 val = da->array[index];
745 *pival = (l_int32)(val + L_SIGN(val) * 0.5);
746 return 0;
747}
748
749
758l_ok
760 l_int32 index,
761 l_float64 val)
762{
763 PROCNAME("l_dnaSetValue");
764
765 if (!da)
766 return ERROR_INT("da not defined", procName, 1);
767 if (index < 0 || index >= da->n)
768 return ERROR_INT("index not valid", procName, 1);
769
770 da->array[index] = val;
771 return 0;
772}
773
774
783l_ok
785 l_int32 index,
786 l_float64 diff)
787{
788 PROCNAME("l_dnaShiftValue");
789
790 if (!da)
791 return ERROR_INT("da not defined", procName, 1);
792 if (index < 0 || index >= da->n)
793 return ERROR_INT("index not valid", procName, 1);
794
795 da->array[index] += diff;
796 return 0;
797}
798
799
819l_int32 *
821{
822l_int32 i, n, ival;
823l_int32 *array;
824
825 PROCNAME("l_dnaGetIArray");
826
827 if (!da)
828 return (l_int32 *)ERROR_PTR("da not defined", procName, NULL);
829
830 n = l_dnaGetCount(da);
831 if ((array = (l_int32 *)LEPT_CALLOC(n, sizeof(l_int32))) == NULL)
832 return (l_int32 *)ERROR_PTR("array not made", procName, NULL);
833 for (i = 0; i < n; i++) {
834 l_dnaGetIValue(da, i, &ival);
835 array[i] = ival;
836 }
837
838 return array;
839}
840
841
863l_float64 *
865 l_int32 copyflag)
866{
867l_int32 i, n;
868l_float64 *array;
869
870 PROCNAME("l_dnaGetDArray");
871
872 if (!da)
873 return (l_float64 *)ERROR_PTR("da not defined", procName, NULL);
874
875 if (copyflag == L_NOCOPY) {
876 array = da->array;
877 } else { /* copyflag == L_COPY */
878 n = l_dnaGetCount(da);
879 if ((array = (l_float64 *)LEPT_CALLOC(n, sizeof(l_float64))) == NULL)
880 return (l_float64 *)ERROR_PTR("array not made", procName, NULL);
881 for (i = 0; i < n; i++)
882 array[i] = da->array[i];
883 }
884
885 return array;
886}
887
888
895l_int32
897{
898 PROCNAME("l_dnaGetRefcount");
899
900 if (!da)
901 return ERROR_INT("da not defined", procName, UNDEF);
902 return da->refcount;
903}
904
905
913l_ok
915 l_int32 delta)
916{
917 PROCNAME("l_dnaChangeRefcount");
918
919 if (!da)
920 return ERROR_INT("da not defined", procName, 1);
921 da->refcount += delta;
922 return 0;
923}
924
925
934l_ok
936 l_float64 *pstartx,
937 l_float64 *pdelx)
938{
939 PROCNAME("l_dnaGetParameters");
940
941 if (pstartx) *pstartx = 0.0;
942 if (pdelx) *pdelx = 1.0;
943 if (!pstartx && !pdelx)
944 return ERROR_INT("neither &startx nor &delx are defined", procName, 1);
945 if (!da)
946 return ERROR_INT("da not defined", procName, 1);
947
948 if (pstartx) *pstartx = da->startx;
949 if (pdelx) *pdelx = da->delx;
950 return 0;
951}
952
953
964l_ok
966 l_float64 startx,
967 l_float64 delx)
968{
969 PROCNAME("l_dnaSetParameters");
970
971 if (!da)
972 return ERROR_INT("da not defined", procName, 1);
973
974 da->startx = startx;
975 da->delx = delx;
976 return 0;
977}
978
979
987l_ok
989 L_DNA *das)
990{
991l_float64 start, binsize;
992
993 PROCNAME("l_dnaCopyParameters");
994
995 if (!das || !dad)
996 return ERROR_INT("das and dad not both defined", procName, 1);
997
998 l_dnaGetParameters(das, &start, &binsize);
999 l_dnaSetParameters(dad, start, binsize);
1000 return 0;
1001}
1002
1003
1004/*----------------------------------------------------------------------*
1005 * Serialize Dna for I/O *
1006 *----------------------------------------------------------------------*/
1013L_DNA *
1014l_dnaRead(const char *filename)
1015{
1016FILE *fp;
1017L_DNA *da;
1018
1019 PROCNAME("l_dnaRead");
1020
1021 if (!filename)
1022 return (L_DNA *)ERROR_PTR("filename not defined", procName, NULL);
1023
1024 if ((fp = fopenReadStream(filename)) == NULL)
1025 return (L_DNA *)ERROR_PTR("stream not opened", procName, NULL);
1026 da = l_dnaReadStream(fp);
1027 fclose(fp);
1028 if (!da)
1029 return (L_DNA *)ERROR_PTR("da not read", procName, NULL);
1030 return da;
1031}
1032
1033
1046L_DNA *
1048{
1049l_int32 i, n, index, ret, version;
1050l_float64 val, startx, delx;
1051L_DNA *da;
1052
1053 PROCNAME("l_dnaReadStream");
1054
1055 if (!fp)
1056 return (L_DNA *)ERROR_PTR("stream not defined", procName, NULL);
1057
1058 ret = fscanf(fp, "\nL_Dna Version %d\n", &version);
1059 if (ret != 1)
1060 return (L_DNA *)ERROR_PTR("not a l_dna file", procName, NULL);
1061 if (version != DNA_VERSION_NUMBER)
1062 return (L_DNA *)ERROR_PTR("invalid l_dna version", procName, NULL);
1063 if (fscanf(fp, "Number of numbers = %d\n", &n) != 1)
1064 return (L_DNA *)ERROR_PTR("invalid number of numbers", procName, NULL);
1065 if (n < 0)
1066 return (L_DNA *)ERROR_PTR("num doubles < 0", procName, NULL);
1067 if (n > MaxDoubleArraySize)
1068 return (L_DNA *)ERROR_PTR("too many doubles", procName, NULL);
1069 if (n == 0) L_INFO("the dna is empty\n", procName);
1070
1071 if ((da = l_dnaCreate(n)) == NULL)
1072 return (L_DNA *)ERROR_PTR("da not made", procName, NULL);
1073 for (i = 0; i < n; i++) {
1074 if (fscanf(fp, " [%d] = %lf\n", &index, &val) != 2) {
1075 l_dnaDestroy(&da);
1076 return (L_DNA *)ERROR_PTR("bad input data", procName, NULL);
1077 }
1078 l_dnaAddNumber(da, val);
1079 }
1080
1081 /* Optional data */
1082 if (fscanf(fp, "startx = %lf, delx = %lf\n", &startx, &delx) == 2)
1083 l_dnaSetParameters(da, startx, delx);
1084 return da;
1085}
1086
1087
1095L_DNA *
1096l_dnaReadMem(const l_uint8 *data,
1097 size_t size)
1098{
1099FILE *fp;
1100L_DNA *da;
1101
1102 PROCNAME("l_dnaReadMem");
1103
1104 if (!data)
1105 return (L_DNA *)ERROR_PTR("data not defined", procName, NULL);
1106 if ((fp = fopenReadFromMemory(data, size)) == NULL)
1107 return (L_DNA *)ERROR_PTR("stream not opened", procName, NULL);
1108
1109 da = l_dnaReadStream(fp);
1110 fclose(fp);
1111 if (!da) L_ERROR("dna not read\n", procName);
1112 return da;
1113}
1114
1115
1123l_ok
1124l_dnaWrite(const char *filename,
1125 L_DNA *da)
1126{
1127l_int32 ret;
1128FILE *fp;
1129
1130 PROCNAME("l_dnaWrite");
1131
1132 if (!filename)
1133 return ERROR_INT("filename not defined", procName, 1);
1134 if (!da)
1135 return ERROR_INT("da not defined", procName, 1);
1136
1137 if ((fp = fopenWriteStream(filename, "w")) == NULL)
1138 return ERROR_INT("stream not opened", procName, 1);
1139 ret = l_dnaWriteStream(fp, da);
1140 fclose(fp);
1141 if (ret)
1142 return ERROR_INT("da not written to stream", procName, 1);
1143 return 0;
1144}
1145
1146
1154l_ok
1156 L_DNA *da)
1157{
1158l_int32 i, n;
1159l_float64 startx, delx;
1160
1161 PROCNAME("l_dnaWriteStream");
1162
1163 if (!da)
1164 return ERROR_INT("da not defined", procName, 1);
1165 if (!fp)
1166 return l_dnaWriteStderr(da);
1167
1168 n = l_dnaGetCount(da);
1169 fprintf(fp, "\nL_Dna Version %d\n", DNA_VERSION_NUMBER);
1170 fprintf(fp, "Number of numbers = %d\n", n);
1171 for (i = 0; i < n; i++)
1172 fprintf(fp, " [%d] = %f\n", i, da->array[i]);
1173 fprintf(fp, "\n");
1174
1175 /* Optional data */
1176 l_dnaGetParameters(da, &startx, &delx);
1177 if (startx != 0.0 || delx != 1.0)
1178 fprintf(fp, "startx = %f, delx = %f\n", startx, delx);
1179
1180 return 0;
1181}
1182
1183
1190l_ok
1192{
1193l_int32 i, n;
1194l_float64 startx, delx;
1195
1196 PROCNAME("l_dnaWriteStderr");
1197
1198 if (!da)
1199 return ERROR_INT("da not defined", procName, 1);
1200
1201 n = l_dnaGetCount(da);
1202 lept_stderr("\nL_Dna Version %d\n", DNA_VERSION_NUMBER);
1203 lept_stderr("Number of numbers = %d\n", n);
1204 for (i = 0; i < n; i++)
1205 lept_stderr(" [%d] = %f\n", i, da->array[i]);
1206 lept_stderr("\n");
1207
1208 /* Optional data */
1209 l_dnaGetParameters(da, &startx, &delx);
1210 if (startx != 0.0 || delx != 1.0)
1211 lept_stderr("startx = %f, delx = %f\n", startx, delx);
1212
1213 return 0;
1214}
1215
1216
1230l_ok
1231l_dnaWriteMem(l_uint8 **pdata,
1232 size_t *psize,
1233 L_DNA *da)
1234{
1235l_int32 ret;
1236FILE *fp;
1237
1238 PROCNAME("l_dnaWriteMem");
1239
1240 if (pdata) *pdata = NULL;
1241 if (psize) *psize = 0;
1242 if (!pdata)
1243 return ERROR_INT("&data not defined", procName, 1);
1244 if (!psize)
1245 return ERROR_INT("&size not defined", procName, 1);
1246 if (!da)
1247 return ERROR_INT("da not defined", procName, 1);
1248
1249#if HAVE_FMEMOPEN
1250 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1251 return ERROR_INT("stream not opened", procName, 1);
1252 ret = l_dnaWriteStream(fp, da);
1253 fputc('\0', fp);
1254 fclose(fp);
1255 *psize = *psize - 1;
1256#else
1257 L_INFO("work-around: writing to a temp file\n", procName);
1258 #ifdef _WIN32
1259 if ((fp = fopenWriteWinTempfile()) == NULL)
1260 return ERROR_INT("tmpfile stream not opened", procName, 1);
1261 #else
1262 if ((fp = tmpfile()) == NULL)
1263 return ERROR_INT("tmpfile stream not opened", procName, 1);
1264 #endif /* _WIN32 */
1265 ret = l_dnaWriteStream(fp, da);
1266 rewind(fp);
1267 *pdata = l_binaryReadStream(fp, psize);
1268 fclose(fp);
1269#endif /* HAVE_FMEMOPEN */
1270 return ret;
1271}
1272
1273
1274/*--------------------------------------------------------------------------*
1275 * Dnaa creation, destruction *
1276 *--------------------------------------------------------------------------*/
1284L_DNAA *
1286{
1287L_DNAA *daa;
1288
1289 PROCNAME("l_dnaaCreate");
1290
1291 if (n <= 0 || n > MaxPtrArraySize)
1292 n = InitialArraySize;
1293
1294 daa = (L_DNAA *)LEPT_CALLOC(1, sizeof(L_DNAA));
1295 if ((daa->dna = (L_DNA **)LEPT_CALLOC(n, sizeof(L_DNA *))) == NULL) {
1296 l_dnaaDestroy(&daa);
1297 return (L_DNAA *)ERROR_PTR("l_dna ptr array not made", procName, NULL);
1298 }
1299 daa->nalloc = n;
1300 daa->n = 0;
1301 return daa;
1302}
1303
1304
1320L_DNAA *
1321l_dnaaCreateFull(l_int32 nptr,
1322 l_int32 n)
1323{
1324l_int32 i;
1325L_DNAA *daa;
1326L_DNA *da;
1327
1328 daa = l_dnaaCreate(nptr);
1329 for (i = 0; i < nptr; i++) {
1330 da = l_dnaCreate(n);
1331 l_dnaaAddDna(daa, da, L_INSERT);
1332 }
1333
1334 return daa;
1335}
1336
1337
1351l_ok
1353{
1354l_int32 i, n, nn;
1355L_DNA *da;
1356
1357 PROCNAME("l_dnaaTruncate");
1358
1359 if (!daa)
1360 return ERROR_INT("daa not defined", procName, 1);
1361
1362 n = l_dnaaGetCount(daa);
1363 for (i = n - 1; i >= 0; i--) {
1364 da = l_dnaaGetDna(daa, i, L_CLONE);
1365 if (!da)
1366 continue;
1367 nn = l_dnaGetCount(da);
1368 l_dnaDestroy(&da); /* the clone */
1369 if (nn == 0)
1370 l_dnaDestroy(&daa->dna[i]);
1371 else
1372 break;
1373 }
1374 daa->n = i + 1;
1375 return 0;
1376}
1377
1378
1385void
1387{
1388l_int32 i;
1389L_DNAA *daa;
1390
1391 PROCNAME("l_dnaaDestroy");
1392
1393 if (pdaa == NULL) {
1394 L_WARNING("ptr address is NULL!\n", procName);
1395 return;
1396 }
1397
1398 if ((daa = *pdaa) == NULL)
1399 return;
1400
1401 for (i = 0; i < daa->n; i++)
1402 l_dnaDestroy(&daa->dna[i]);
1403 LEPT_FREE(daa->dna);
1404 LEPT_FREE(daa);
1405 *pdaa = NULL;
1406}
1407
1408
1409/*--------------------------------------------------------------------------*
1410 * Add Dna to Dnaa *
1411 *--------------------------------------------------------------------------*/
1420l_ok
1422 L_DNA *da,
1423 l_int32 copyflag)
1424{
1425l_int32 n;
1426L_DNA *dac;
1427
1428 PROCNAME("l_dnaaAddDna");
1429
1430 if (!daa)
1431 return ERROR_INT("daa not defined", procName, 1);
1432 if (!da)
1433 return ERROR_INT("da not defined", procName, 1);
1434
1435 if (copyflag == L_INSERT) {
1436 dac = da;
1437 } else if (copyflag == L_COPY) {
1438 if ((dac = l_dnaCopy(da)) == NULL)
1439 return ERROR_INT("dac not made", procName, 1);
1440 } else if (copyflag == L_CLONE) {
1441 dac = l_dnaClone(da);
1442 } else {
1443 return ERROR_INT("invalid copyflag", procName, 1);
1444 }
1445
1446 n = l_dnaaGetCount(daa);
1447 if (n >= daa->nalloc) {
1448 if (l_dnaaExtendArray(daa)) {
1449 if (copyflag != L_INSERT)
1450 l_dnaDestroy(&dac);
1451 return ERROR_INT("extension failed", procName, 1);
1452 }
1453 }
1454 daa->dna[n] = dac;
1455 daa->n++;
1456 return 0;
1457}
1458
1459
1472static l_int32
1474{
1475size_t oldsize, newsize;
1476
1477 PROCNAME("l_dnaaExtendArray");
1478
1479 if (!daa)
1480 return ERROR_INT("daa not defined", procName, 1);
1481 if (daa->nalloc > MaxPtrArraySize) /* belt & suspenders */
1482 return ERROR_INT("daa has too many ptrs", procName, 1);
1483 oldsize = daa->nalloc * sizeof(L_DNA *);
1484 newsize = 2 * oldsize;
1485 if (newsize > 8 * MaxPtrArraySize)
1486 return ERROR_INT("newsize > 8 MB; too large", procName, 1);
1487
1488 if ((daa->dna = (L_DNA **)reallocNew((void **)&daa->dna,
1489 oldsize, newsize)) == NULL)
1490 return ERROR_INT("new ptr array not returned", procName, 1);
1491
1492 daa->nalloc *= 2;
1493 return 0;
1494}
1495
1496
1497/*----------------------------------------------------------------------*
1498 * DNumaa accessors *
1499 *----------------------------------------------------------------------*/
1506l_int32
1508{
1509 PROCNAME("l_dnaaGetCount");
1510
1511 if (!daa)
1512 return ERROR_INT("daa not defined", procName, 0);
1513 return daa->n;
1514}
1515
1516
1524l_int32
1526 l_int32 index)
1527{
1528 PROCNAME("l_dnaaGetDnaCount");
1529
1530 if (!daa)
1531 return ERROR_INT("daa not defined", procName, 0);
1532 if (index < 0 || index >= daa->n)
1533 return ERROR_INT("invalid index into daa", procName, 0);
1534 return l_dnaGetCount(daa->dna[index]);
1535}
1536
1537
1545l_int32
1547{
1548L_DNA *da;
1549l_int32 n, sum, i;
1550
1551 PROCNAME("l_dnaaGetNumberCount");
1552
1553 if (!daa)
1554 return ERROR_INT("daa not defined", procName, 0);
1555
1556 n = l_dnaaGetCount(daa);
1557 for (sum = 0, i = 0; i < n; i++) {
1558 da = l_dnaaGetDna(daa, i, L_CLONE);
1559 sum += l_dnaGetCount(da);
1560 l_dnaDestroy(&da);
1561 }
1562
1563 return sum;
1564}
1565
1566
1575L_DNA *
1577 l_int32 index,
1578 l_int32 accessflag)
1579{
1580 PROCNAME("l_dnaaGetDna");
1581
1582 if (!daa)
1583 return (L_DNA *)ERROR_PTR("daa not defined", procName, NULL);
1584 if (index < 0 || index >= daa->n)
1585 return (L_DNA *)ERROR_PTR("index not valid", procName, NULL);
1586
1587 if (accessflag == L_COPY)
1588 return l_dnaCopy(daa->dna[index]);
1589 else if (accessflag == L_CLONE)
1590 return l_dnaClone(daa->dna[index]);
1591 else
1592 return (L_DNA *)ERROR_PTR("invalid accessflag", procName, NULL);
1593}
1594
1595
1611l_ok
1613 l_int32 index,
1614 L_DNA *da)
1615{
1616l_int32 n;
1617
1618 PROCNAME("l_dnaaReplaceDna");
1619
1620 if (!daa)
1621 return ERROR_INT("daa not defined", procName, 1);
1622 if (!da)
1623 return ERROR_INT("da not defined", procName, 1);
1624 n = l_dnaaGetCount(daa);
1625 if (index < 0 || index >= n)
1626 return ERROR_INT("index not valid", procName, 1);
1627
1628 l_dnaDestroy(&daa->dna[index]);
1629 daa->dna[index] = da;
1630 return 0;
1631}
1632
1633
1643l_ok
1645 l_int32 i,
1646 l_int32 j,
1647 l_float64 *pval)
1648{
1649l_int32 n;
1650L_DNA *da;
1651
1652 PROCNAME("l_dnaaGetValue");
1653
1654 if (!pval)
1655 return ERROR_INT("&val not defined", procName, 1);
1656 *pval = 0.0;
1657 if (!daa)
1658 return ERROR_INT("daa not defined", procName, 1);
1659 n = l_dnaaGetCount(daa);
1660 if (i < 0 || i >= n)
1661 return ERROR_INT("invalid index into daa", procName, 1);
1662 da = daa->dna[i];
1663 if (j < 0 || j >= da->n)
1664 return ERROR_INT("invalid index into da", procName, 1);
1665 *pval = da->array[j];
1666 return 0;
1667}
1668
1669
1683l_ok
1685 l_int32 index,
1686 l_float64 val)
1687{
1688l_int32 n;
1689L_DNA *da;
1690
1691 PROCNAME("l_dnaaAddNumber");
1692
1693 if (!daa)
1694 return ERROR_INT("daa not defined", procName, 1);
1695 n = l_dnaaGetCount(daa);
1696 if (index < 0 || index >= n)
1697 return ERROR_INT("invalid index in daa", procName, 1);
1698
1699 da = l_dnaaGetDna(daa, index, L_CLONE);
1700 l_dnaAddNumber(da, val);
1701 l_dnaDestroy(&da);
1702 return 0;
1703}
1704
1705
1706/*----------------------------------------------------------------------*
1707 * Serialize Dna for I/O *
1708 *----------------------------------------------------------------------*/
1715L_DNAA *
1716l_dnaaRead(const char *filename)
1717{
1718FILE *fp;
1719L_DNAA *daa;
1720
1721 PROCNAME("l_dnaaRead");
1722
1723 if (!filename)
1724 return (L_DNAA *)ERROR_PTR("filename not defined", procName, NULL);
1725
1726 if ((fp = fopenReadStream(filename)) == NULL)
1727 return (L_DNAA *)ERROR_PTR("stream not opened", procName, NULL);
1728 daa = l_dnaaReadStream(fp);
1729 fclose(fp);
1730 if (!daa)
1731 return (L_DNAA *)ERROR_PTR("daa not read", procName, NULL);
1732 return daa;
1733}
1734
1735
1747L_DNAA *
1749{
1750l_int32 i, n, index, ret, version;
1751L_DNA *da;
1752L_DNAA *daa;
1753
1754 PROCNAME("l_dnaaReadStream");
1755
1756 if (!fp)
1757 return (L_DNAA *)ERROR_PTR("stream not defined", procName, NULL);
1758
1759 ret = fscanf(fp, "\nL_Dnaa Version %d\n", &version);
1760 if (ret != 1)
1761 return (L_DNAA *)ERROR_PTR("not a l_dna file", procName, NULL);
1762 if (version != DNA_VERSION_NUMBER)
1763 return (L_DNAA *)ERROR_PTR("invalid l_dnaa version", procName, NULL);
1764 if (fscanf(fp, "Number of L_Dna = %d\n\n", &n) != 1)
1765 return (L_DNAA *)ERROR_PTR("invalid number of l_dna", procName, NULL);
1766 if (n < 0)
1767 return (L_DNAA *)ERROR_PTR("num l_dna <= 0", procName, NULL);
1768 if (n > MaxPtrArraySize)
1769 return (L_DNAA *)ERROR_PTR("too many l_dna", procName, NULL);
1770 if (n == 0) L_INFO("the dnaa is empty\n", procName);
1771
1772 if ((daa = l_dnaaCreate(n)) == NULL)
1773 return (L_DNAA *)ERROR_PTR("daa not made", procName, NULL);
1774 for (i = 0; i < n; i++) {
1775 if (fscanf(fp, "L_Dna[%d]:", &index) != 1) {
1776 l_dnaaDestroy(&daa);
1777 return (L_DNAA *)ERROR_PTR("invalid l_dna header", procName, NULL);
1778 }
1779 if ((da = l_dnaReadStream(fp)) == NULL) {
1780 l_dnaaDestroy(&daa);
1781 return (L_DNAA *)ERROR_PTR("da not made", procName, NULL);
1782 }
1783 l_dnaaAddDna(daa, da, L_INSERT);
1784 }
1785
1786 return daa;
1787}
1788
1789
1797L_DNAA *
1798l_dnaaReadMem(const l_uint8 *data,
1799 size_t size)
1800{
1801FILE *fp;
1802L_DNAA *daa;
1803
1804 PROCNAME("l_dnaaReadMem");
1805
1806 if (!data)
1807 return (L_DNAA *)ERROR_PTR("data not defined", procName, NULL);
1808 if ((fp = fopenReadFromMemory(data, size)) == NULL)
1809 return (L_DNAA *)ERROR_PTR("stream not opened", procName, NULL);
1810
1811 daa = l_dnaaReadStream(fp);
1812 fclose(fp);
1813 if (!daa) L_ERROR("daa not read\n", procName);
1814 return daa;
1815}
1816
1817
1825l_ok
1826l_dnaaWrite(const char *filename,
1827 L_DNAA *daa)
1828{
1829l_int32 ret;
1830FILE *fp;
1831
1832 PROCNAME("l_dnaaWrite");
1833
1834 if (!filename)
1835 return ERROR_INT("filename not defined", procName, 1);
1836 if (!daa)
1837 return ERROR_INT("daa not defined", procName, 1);
1838
1839 if ((fp = fopenWriteStream(filename, "w")) == NULL)
1840 return ERROR_INT("stream not opened", procName, 1);
1841 ret = l_dnaaWriteStream(fp, daa);
1842 fclose(fp);
1843 if (ret)
1844 return ERROR_INT("daa not written to stream", procName, 1);
1845 return 0;
1846}
1847
1848
1856l_ok
1858 L_DNAA *daa)
1859{
1860l_int32 i, n;
1861L_DNA *da;
1862
1863 PROCNAME("l_dnaaWriteStream");
1864
1865 if (!fp)
1866 return ERROR_INT("stream not defined", procName, 1);
1867 if (!daa)
1868 return ERROR_INT("daa not defined", procName, 1);
1869
1870 n = l_dnaaGetCount(daa);
1871 fprintf(fp, "\nL_Dnaa Version %d\n", DNA_VERSION_NUMBER);
1872 fprintf(fp, "Number of L_Dna = %d\n\n", n);
1873 for (i = 0; i < n; i++) {
1874 if ((da = l_dnaaGetDna(daa, i, L_CLONE)) == NULL)
1875 return ERROR_INT("da not found", procName, 1);
1876 fprintf(fp, "L_Dna[%d]:", i);
1877 l_dnaWriteStream(fp, da);
1878 l_dnaDestroy(&da);
1879 }
1880
1881 return 0;
1882}
1883
1884
1898l_ok
1899l_dnaaWriteMem(l_uint8 **pdata,
1900 size_t *psize,
1901 L_DNAA *daa)
1902{
1903l_int32 ret;
1904FILE *fp;
1905
1906 PROCNAME("l_dnaaWriteMem");
1907
1908 if (pdata) *pdata = NULL;
1909 if (psize) *psize = 0;
1910 if (!pdata)
1911 return ERROR_INT("&data not defined", procName, 1);
1912 if (!psize)
1913 return ERROR_INT("&size not defined", procName, 1);
1914 if (!daa)
1915 return ERROR_INT("daa not defined", procName, 1);
1916
1917#if HAVE_FMEMOPEN
1918 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1919 return ERROR_INT("stream not opened", procName, 1);
1920 ret = l_dnaaWriteStream(fp, daa);
1921 fputc('\0', fp);
1922 fclose(fp);
1923 *psize = *psize - 1;
1924#else
1925 L_INFO("work-around: writing to a temp file\n", procName);
1926 #ifdef _WIN32
1927 if ((fp = fopenWriteWinTempfile()) == NULL)
1928 return ERROR_INT("tmpfile stream not opened", procName, 1);
1929 #else
1930 if ((fp = tmpfile()) == NULL)
1931 return ERROR_INT("tmpfile stream not opened", procName, 1);
1932 #endif /* _WIN32 */
1933 ret = l_dnaaWriteStream(fp, daa);
1934 rewind(fp);
1935 *pdata = l_binaryReadStream(fp, psize);
1936 fclose(fp);
1937#endif /* HAVE_FMEMOPEN */
1938 return ret;
1939}
1940
#define DNA_VERSION_NUMBER
Definition: array.h:91
L_DNA * l_dnaReadMem(const l_uint8 *data, size_t size)
l_dnaReadMem()
Definition: dnabasic.c:1096
l_ok l_dnaWriteStream(FILE *fp, L_DNA *da)
l_dnaWriteStream()
Definition: dnabasic.c:1155
l_ok l_dnaaReplaceDna(L_DNAA *daa, l_int32 index, L_DNA *da)
l_dnaaReplaceDna()
Definition: dnabasic.c:1612
l_int32 l_dnaaGetCount(L_DNAA *daa)
l_dnaaGetCount()
Definition: dnabasic.c:1507
L_DNA * l_dnaCreateFromDArray(l_float64 *darray, l_int32 size, l_int32 copyflag)
l_dnaCreateFromDArray()
Definition: dnabasic.c:258
l_int32 l_dnaaGetDnaCount(L_DNAA *daa, l_int32 index)
l_dnaaGetDnaCount()
Definition: dnabasic.c:1525
l_ok l_dnaGetIValue(L_DNA *da, l_int32 index, l_int32 *pival)
l_dnaGetIValue()
Definition: dnabasic.c:727
l_ok l_dnaAddNumber(L_DNA *da, l_float64 val)
l_dnaAddNumber()
Definition: dnabasic.c:448
l_ok l_dnaCopyParameters(L_DNA *dad, L_DNA *das)
l_dnaCopyParameters()
Definition: dnabasic.c:988
l_ok l_dnaaTruncate(L_DNAA *daa)
l_dnaaTruncate()
Definition: dnabasic.c:1352
L_DNAA * l_dnaaCreate(l_int32 n)
l_dnaaCreate()
Definition: dnabasic.c:1285
l_ok l_dnaSetValue(L_DNA *da, l_int32 index, l_float64 val)
l_dnaSetValue()
Definition: dnabasic.c:759
static l_int32 l_dnaaExtendArray(L_DNAA *daa)
l_dnaaExtendArray()
Definition: dnabasic.c:1473
l_ok l_dnaaAddNumber(L_DNAA *daa, l_int32 index, l_float64 val)
l_dnaaAddNumber()
Definition: dnabasic.c:1684
static l_int32 l_dnaExtendArray(L_DNA *da)
l_dnaExtendArray()
Definition: dnabasic.c:482
l_ok l_dnaaWriteStream(FILE *fp, L_DNAA *daa)
l_dnaaWriteStream()
Definition: dnabasic.c:1857
L_DNA * l_dnaClone(L_DNA *da)
l_dnaClone()
Definition: dnabasic.c:398
l_ok l_dnaShiftValue(L_DNA *da, l_int32 index, l_float64 diff)
l_dnaShiftValue()
Definition: dnabasic.c:784
l_ok l_dnaRemoveNumber(L_DNA *da, l_int32 index)
l_dnaRemoveNumber()
Definition: dnabasic.c:569
L_DNA * l_dnaMakeSequence(l_float64 startval, l_float64 increment, l_int32 size)
l_dnaMakeSequence()
Definition: dnabasic.c:297
L_DNAA * l_dnaaCreateFull(l_int32 nptr, l_int32 n)
l_dnaaCreateFull()
Definition: dnabasic.c:1321
l_ok l_dnaEmpty(L_DNA *da)
l_dnaEmpty()
Definition: dnabasic.c:424
l_ok l_dnaSetParameters(L_DNA *da, l_float64 startx, l_float64 delx)
l_dnaSetParameters()
Definition: dnabasic.c:965
l_int32 l_dnaGetRefcount(L_DNA *da)
l_dnaGetRefCount()
Definition: dnabasic.c:896
l_ok l_dnaaWrite(const char *filename, L_DNAA *daa)
l_dnaaWrite()
Definition: dnabasic.c:1826
L_DNAA * l_dnaaReadStream(FILE *fp)
l_dnaaReadStream()
Definition: dnabasic.c:1748
L_DNA * l_dnaCreateFromIArray(l_int32 *iarray, l_int32 size)
l_dnaCreateFromIArray()
Definition: dnabasic.c:221
L_DNA * l_dnaCopy(L_DNA *da)
l_dnaCopy()
Definition: dnabasic.c:369
L_DNA * l_dnaRead(const char *filename)
l_dnaRead()
Definition: dnabasic.c:1014
l_ok l_dnaGetDValue(L_DNA *da, l_int32 index, l_float64 *pval)
l_dnaGetDValue()
Definition: dnabasic.c:692
static const l_int32 InitialArraySize
Definition: dnabasic.c:164
l_ok l_dnaaWriteMem(l_uint8 **pdata, size_t *psize, L_DNAA *daa)
l_dnaaWriteMem()
Definition: dnabasic.c:1899
L_DNA * l_dnaCreate(l_int32 n)
l_dnaCreate()
Definition: dnabasic.c:180
l_ok l_dnaInsertNumber(L_DNA *da, l_int32 index, l_float64 val)
l_dnaInsertNumber()
Definition: dnabasic.c:526
l_int32 l_dnaaGetNumberCount(L_DNAA *daa)
l_dnaaGetNumberCount()
Definition: dnabasic.c:1546
L_DNAA * l_dnaaReadMem(const l_uint8 *data, size_t size)
l_dnaaReadMem()
Definition: dnabasic.c:1798
L_DNA * l_dnaReadStream(FILE *fp)
l_dnaReadStream()
Definition: dnabasic.c:1047
l_ok l_dnaSetCount(L_DNA *da, l_int32 newcount)
l_dnaSetCount()
Definition: dnabasic.c:658
l_ok l_dnaaAddDna(L_DNAA *daa, L_DNA *da, l_int32 copyflag)
l_dnaaAddDna()
Definition: dnabasic.c:1421
l_int32 * l_dnaGetIArray(L_DNA *da)
l_dnaGetIArray()
Definition: dnabasic.c:820
l_ok l_dnaaGetValue(L_DNAA *daa, l_int32 i, l_int32 j, l_float64 *pval)
l_dnaaGetValue()
Definition: dnabasic.c:1644
l_ok l_dnaWriteStderr(L_DNA *da)
l_dnaWriteStrderr()
Definition: dnabasic.c:1191
l_ok l_dnaChangeRefcount(L_DNA *da, l_int32 delta)
l_dnaChangeRefCount()
Definition: dnabasic.c:914
l_ok l_dnaReplaceNumber(L_DNA *da, l_int32 index, l_float64 val)
l_dnaReplaceNumber()
Definition: dnabasic.c:600
l_float64 * l_dnaGetDArray(L_DNA *da, l_int32 copyflag)
l_dnaGetDArray()
Definition: dnabasic.c:864
L_DNAA * l_dnaaRead(const char *filename)
l_dnaaRead()
Definition: dnabasic.c:1716
void l_dnaDestroy(L_DNA **pda)
l_dnaDestroy()
Definition: dnabasic.c:332
l_ok l_dnaGetParameters(L_DNA *da, l_float64 *pstartx, l_float64 *pdelx)
l_dnaGetParameters()
Definition: dnabasic.c:935
l_ok l_dnaWriteMem(l_uint8 **pdata, size_t *psize, L_DNA *da)
l_dnaWriteMem()
Definition: dnabasic.c:1231
l_ok l_dnaWrite(const char *filename, L_DNA *da)
l_dnaWrite()
Definition: dnabasic.c:1124
l_int32 l_dnaGetCount(L_DNA *da)
l_dnaGetCount()
Definition: dnabasic.c:631
void l_dnaaDestroy(L_DNAA **pdaa)
l_dnaaDestroy()
Definition: dnabasic.c:1386
L_DNA * l_dnaaGetDna(L_DNAA *daa, l_int32 index, l_int32 accessflag)
l_dnaaGetDna()
Definition: dnabasic.c:1576
@ L_COPY
Definition: pix.h:712
@ L_CLONE
Definition: pix.h:713
@ L_NOCOPY
Definition: pix.h:710
@ L_INSERT
Definition: pix.h:711
Definition: array.h:95
l_float64 startx
Definition: array.h:99
l_int32 refcount
Definition: array.h:98
l_int32 n
Definition: array.h:97
l_float64 * array
Definition: array.h:101
l_int32 nalloc
Definition: array.h:96
l_float64 delx
Definition: array.h:100
Definition: array.h:107
l_int32 n
Definition: array.h:109
l_int32 nalloc
Definition: array.h:108
struct L_Dna ** dna
Definition: array.h:110
void lept_stderr(const char *fmt,...)
lept_stderr()
Definition: utils1.c:306
FILE * fopenWriteWinTempfile(void)
fopenWriteWinTempfile()
Definition: utils2.c:2055
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1975
FILE * fopenReadFromMemory(const l_uint8 *data, size_t size)
fopenReadFromMemory()
Definition: utils2.c:2009
FILE * fopenReadStream(const char *filename)
fopenReadStream()
Definition: utils2.c:1932
l_uint8 * l_binaryReadStream(FILE *fp, size_t *pnbytes)
l_binaryReadStream()
Definition: utils2.c:1402
void * reallocNew(void **pindata, size_t oldsize, size_t newsize)
reallocNew()
Definition: utils2.c:1302