comparison mupdf-source/thirdparty/leptonica/src/dnabasic.c @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
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
27 /*!
28 * \file dnabasic.c
29 * <pre>
30 *
31 * Dna creation, destruction, copy, clone, etc.
32 * L_DNA *l_dnaCreate()
33 * L_DNA *l_dnaCreateFromIArray()
34 * L_DNA *l_dnaCreateFromDArray()
35 * L_DNA *l_dnaMakeSequence()
36 * void *l_dnaDestroy()
37 * L_DNA *l_dnaCopy()
38 * L_DNA *l_dnaClone()
39 * l_int32 l_dnaEmpty()
40 *
41 * Dna: add/remove number and extend array
42 * l_int32 l_dnaAddNumber()
43 * static l_int32 l_dnaExtendArray()
44 * l_int32 l_dnaInsertNumber()
45 * l_int32 l_dnaRemoveNumber()
46 * l_int32 l_dnaReplaceNumber()
47 *
48 * Dna accessors
49 * l_int32 l_dnaGetCount()
50 * l_int32 l_dnaSetCount()
51 * l_int32 l_dnaGetIValue()
52 * l_int32 l_dnaGetDValue()
53 * l_int32 l_dnaSetValue()
54 * l_int32 l_dnaShiftValue()
55 * l_int32 *l_dnaGetIArray()
56 * l_float64 *l_dnaGetDArray()
57 * l_int32 l_dnaGetParameters()
58 * l_int32 l_dnaSetParameters()
59 * l_int32 l_dnaCopyParameters()
60 *
61 * Serialize Dna for I/O
62 * L_DNA *l_dnaRead()
63 * L_DNA *l_dnaReadStream()
64 * L_DNA *l_dnaReadMem()
65 * l_int32 l_dnaWrite()
66 * l_int32 l_dnaWriteStream()
67 * l_int32 l_dnaWriteStderr()
68 * l_int32 l_dnaWriteMem()
69 *
70 * Dnaa creation, destruction
71 * L_DNAA *l_dnaaCreate()
72 * L_DNAA *l_dnaaCreateFull()
73 * l_int32 l_dnaaTruncate()
74 * void *l_dnaaDestroy()
75 *
76 * Add Dna to Dnaa
77 * l_int32 l_dnaaAddDna()
78 * static l_int32 l_dnaaExtendArray()
79 *
80 * Dnaa accessors
81 * l_int32 l_dnaaGetCount()
82 * l_int32 l_dnaaGetDnaCount()
83 * l_int32 l_dnaaGetNumberCount()
84 * L_DNA *l_dnaaGetDna()
85 * L_DNA *l_dnaaReplaceDna()
86 * l_int32 l_dnaaGetValue()
87 * l_int32 l_dnaaAddNumber()
88 *
89 * Serialize Dnaa for I/O
90 * L_DNAA *l_dnaaRead()
91 * L_DNAA *l_dnaaReadStream()
92 * L_DNAA *l_dnaaReadMem()
93 * l_int32 l_dnaaWrite()
94 * l_int32 l_dnaaWriteStream()
95 * l_int32 l_dnaaWriteMem()
96 *
97 * (1) The Dna is a struct holding an array of doubles. It can also
98 * be used to store l_int32 values, up to the full precision
99 * of int32. Always use it whenever integers larger than a
100 * few million need to be stored.
101 *
102 * (2) Always use the accessors in this file, never the fields directly.
103 *
104 * (3) Storing and retrieving numbers:
105 *
106 * * to append a new number to the array, use l_dnaAddNumber(). If
107 * the number is an int, it will will automatically be converted
108 * to l_float64 and stored.
109 *
110 * * to reset a value stored in the array, use l_dnaSetValue().
111 *
112 * * to increment or decrement a value stored in the array,
113 * use l_dnaShiftValue().
114 *
115 * * to obtain a value from the array, use either l_dnaGetIValue()
116 * or l_dnaGetDValue(), depending on whether you are retrieving
117 * an integer or a float64. This avoids doing an explicit cast,
118 * such as
119 * (a) return a l_float64 and cast it to an l_int32
120 * (b) cast the return directly to (l_float64 *) to
121 * satisfy the function prototype, as in
122 * l_dnaGetDValue(da, index, (l_float64 *)&ival); [ugly!]
123 *
124 * (4) int <--> double conversions:
125 *
126 * Conversions go automatically from l_int32 --> l_float64,
127 * without loss of precision. You must cast (l_int32)
128 * to go from l_float64 --> l_int32 because you're truncating
129 * to the integer value.
130 *
131 * (5) As with other arrays in leptonica, the l_dna has both an allocated
132 * size and a count of the stored numbers. When you add a number, it
133 * goes on the end of the array, and causes a realloc if the array
134 * is already filled. However, in situations where you want to
135 * add numbers randomly into an array, such as when you build a
136 * histogram, you must set the count of stored numbers in advance.
137 * This is done with l_dnaSetCount(). If you set a count larger
138 * than the allocated array, it does a realloc to the size requested.
139 *
140 * (6) In situations where the data in a l_dna correspond to a function
141 * y(x), the values can be either at equal spacings in x or at
142 * arbitrary spacings. For the former, we can represent all x values
143 * by two parameters: startx (corresponding to y[0]) and delx
144 * for the change in x for adjacent values y[i] and y[i+1].
145 * startx and delx are initialized to 0.0 and 1.0, rsp.
146 * For arbitrary spacings, we use a second l_dna, and the two
147 * l_dnas are typically denoted dnay and dnax.
148 * </pre>
149 */
150
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; /*!< n'importe quoi */
164
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 *--------------------------------------------------------------------------*/
172 /*!
173 * \brief l_dnaCreate()
174 *
175 * \param[in] n size of number array to be alloc'd; 0 for default
176 * \return da, or NULL on error
177 */
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
202 /*!
203 * \brief l_dnaCreateFromIArray()
204 *
205 * \param[in] iarray integer array
206 * \param[in] size of the array
207 * \return da, or NULL on error
208 *
209 * <pre>
210 * Notes:
211 * (1) We can't insert this int array into the l_dna, because a l_dna
212 * takes a double array. So this just copies the data from the
213 * input array into the l_dna. The input array continues to be
214 * owned by the caller.
215 * </pre>
216 */
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
237 /*!
238 * \brief l_dnaCreateFromDArray()
239 *
240 * \param[in] darray float
241 * \param[in] size of the array
242 * \param[in] copyflag L_INSERT or L_COPY
243 * \return da, or NULL on error
244 *
245 * <pre>
246 * Notes:
247 * (1) With L_INSERT, ownership of the input array is transferred
248 * to the returned l_dna, and all %size elements are considered
249 * to be valid.
250 * </pre>
251 */
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
281 /*!
282 * \brief l_dnaMakeSequence()
283 *
284 * \param[in] startval
285 * \param[in] increment
286 * \param[in] size of sequence
287 * \return l_dna of sequence of evenly spaced values, or NULL on error
288 */
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
310 /*!
311 * \brief l_dnaDestroy()
312 *
313 * \param[in,out] pda will be set to null before returning
314 * \return void
315 *
316 * <pre>
317 * Notes:
318 * (1) Decrements the ref count and, if 0, destroys the l_dna.
319 * (2) Always nulls the input ptr.
320 * </pre>
321 */
322 void
323 l_dnaDestroy(L_DNA **pda)
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
345 /*!
346 * \brief l_dnaCopy()
347 *
348 * \param[in] da
349 * \return copy of da, or NULL on error
350 *
351 * <pre>
352 * Notes:
353 * (1) This removes unused ptrs above da->n.
354 * </pre>
355 */
356 L_DNA *
357 l_dnaCopy(L_DNA *da)
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
377 /*!
378 * \brief l_dnaClone()
379 *
380 * \param[in] da
381 * \return ptr to same da, or NULL on error
382 */
383 L_DNA *
384 l_dnaClone(L_DNA *da)
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
394 /*!
395 * \brief l_dnaEmpty()
396 *
397 * \param[in] da
398 * \return 0 if OK; 1 on error
399 *
400 * <pre>
401 * Notes:
402 * (1) This does not change the allocation of the array.
403 * It just clears the number of stored numbers, so that
404 * the array appears to be empty.
405 * </pre>
406 */
407 l_ok
408 l_dnaEmpty(L_DNA *da)
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 *--------------------------------------------------------------------------*/
422 /*!
423 * \brief l_dnaAddNumber()
424 *
425 * \param[in] da
426 * \param[in] val float or int to be added; stored as a float
427 * \return 0 if OK, 1 on error
428 */
429 l_ok
430 l_dnaAddNumber(L_DNA *da,
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
449 /*!
450 * \brief l_dnaExtendArray()
451 *
452 * \param[in] da
453 * \return 0 if OK, 1 on error
454 *
455 * <pre>
456 * Notes:
457 * (1) Doubles the size of the array.
458 * (2) The max number of doubles is 100M.
459 * </pre>
460 */
461 static l_int32
462 l_dnaExtendArray(L_DNA *da)
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
486 /*!
487 * \brief l_dnaInsertNumber()
488 *
489 * \param[in] da
490 * \param[in] index location in da to insert new value
491 * \param[in] val float64 or integer to be added
492 * \return 0 if OK, 1 on error
493 *
494 * <pre>
495 * Notes:
496 * (1) This shifts da[i] --> da[i + 1] for all i >= %index,
497 * and then inserts %val as da[%index].
498 * (2) It should not be used repeatedly on large arrays,
499 * because the function is O(n).
500 *
501 * </pre>
502 */
503 l_ok
504 l_dnaInsertNumber(L_DNA *da,
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
530 /*!
531 * \brief l_dnaRemoveNumber()
532 *
533 * \param[in] da
534 * \param[in] index element to be removed
535 * \return 0 if OK, 1 on error
536 *
537 * <pre>
538 * Notes:
539 * (1) This shifts da[i] --> da[i - 1] for all i > %index.
540 * (2) It should not be used repeatedly on large arrays,
541 * because the function is O(n).
542 * </pre>
543 */
544 l_ok
545 l_dnaRemoveNumber(L_DNA *da,
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
565 /*!
566 * \brief l_dnaReplaceNumber()
567 *
568 * \param[in] da
569 * \param[in] index element to be replaced
570 * \param[in] val new value to replace old one
571 * \return 0 if OK, 1 on error
572 */
573 l_ok
574 l_dnaReplaceNumber(L_DNA *da,
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 *----------------------------------------------------------------------*/
596 /*!
597 * \brief l_dnaGetCount()
598 *
599 * \param[in] da
600 * \return count, or 0 if no numbers or on error
601 */
602 l_int32
603 l_dnaGetCount(L_DNA *da)
604 {
605 if (!da)
606 return ERROR_INT("da not defined", __func__, 0);
607 return da->n;
608 }
609
610
611 /*!
612 * \brief l_dnaSetCount()
613 *
614 * \param[in] da
615 * \param[in] newcount
616 * \return 0 if OK, 1 on error
617 *
618 * <pre>
619 * Notes:
620 * (1) If %newcount <= da->nalloc, this resets da->n.
621 * Using %newcount = 0 is equivalent to l_dnaEmpty().
622 * (2) If %newcount > da->nalloc, this causes a realloc
623 * to a size da->nalloc = %newcount.
624 * (3) All the previously unused values in da are set to 0.0.
625 * </pre>
626 */
627 l_ok
628 l_dnaSetCount(L_DNA *da,
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
645 /*!
646 * \brief l_dnaGetDValue()
647 *
648 * \param[in] da
649 * \param[in] index into l_dna
650 * \param[out] pval double value; 0.0 on error
651 * \return 0 if OK; 1 on error
652 *
653 * <pre>
654 * Notes:
655 * (1) Caller may need to check the function return value to
656 * decide if a 0.0 in the returned ival is valid.
657 * </pre>
658 */
659 l_ok
660 l_dnaGetDValue(L_DNA *da,
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
678 /*!
679 * \brief l_dnaGetIValue()
680 *
681 * \param[in] da
682 * \param[in] index into l_dna
683 * \param[out] pival integer value; 0 on error
684 * \return 0 if OK; 1 on error
685 *
686 * <pre>
687 * Notes:
688 * (1) Caller may need to check the function return value to
689 * decide if a 0 in the returned ival is valid.
690 * </pre>
691 */
692 l_ok
693 l_dnaGetIValue(L_DNA *da,
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
714 /*!
715 * \brief l_dnaSetValue()
716 *
717 * \param[in] da
718 * \param[in] index to element to be set
719 * \param[in] val to set element
720 * \return 0 if OK; 1 on error
721 */
722 l_ok
723 l_dnaSetValue(L_DNA *da,
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
737 /*!
738 * \brief l_dnaShiftValue()
739 *
740 * \param[in] da
741 * \param[in] index to element to change relative to the current value
742 * \param[in] diff increment if diff > 0 or decrement if diff < 0
743 * \return 0 if OK; 1 on error
744 */
745 l_ok
746 l_dnaShiftValue(L_DNA *da,
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
760 /*!
761 * \brief l_dnaGetIArray()
762 *
763 * \param[in] da
764 * \return a copy of the bare internal array, integerized
765 * by rounding, or NULL on error
766 * <pre>
767 * Notes:
768 * (1) A copy of the array is made, because we need to
769 * generate an integer array from the bare double array.
770 * The caller is responsible for freeing the array.
771 * (2) The array size is determined by the number of stored numbers,
772 * not by the size of the allocated array in the l_dna.
773 * (3) This function is provided to simplify calculations
774 * using the bare internal array, rather than continually
775 * calling accessors on the l_dna. It is typically used
776 * on an array of size 256.
777 * </pre>
778 */
779 l_int32 *
780 l_dnaGetIArray(L_DNA *da)
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
800 /*!
801 * \brief l_dnaGetDArray()
802 *
803 * \param[in] da
804 * \param[in] copyflag L_NOCOPY or L_COPY
805 * \return either the bare internal array or a copy of it, or NULL on error
806 *
807 * <pre>
808 * Notes:
809 * (1) If %copyflag == L_COPY, it makes a copy which the caller
810 * is responsible for freeing. Otherwise, it operates
811 * directly on the bare array of the l_dna.
812 * (2) Very important: for L_NOCOPY, any writes to the array
813 * will be in the l_dna. Do not write beyond the size of
814 * the count field, because it will not be accessible
815 * from the l_dna! If necessary, be sure to set the count
816 * field to a larger number (such as the alloc size)
817 * BEFORE calling this function. Creating with l_dnaMakeConstant()
818 * is another way to insure full initialization.
819 * </pre>
820 */
821 l_float64 *
822 l_dnaGetDArray(L_DNA *da,
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
845 /*!
846 * \brief l_dnaGetParameters()
847 *
848 * \param[in] da
849 * \param[out] pstartx [optional] startx
850 * \param[out] pdelx [optional] delx
851 * \return 0 if OK, 1 on error
852 */
853 l_ok
854 l_dnaGetParameters(L_DNA *da,
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
871 /*!
872 * \brief l_dnaSetParameters()
873 *
874 * \param[in] da
875 * \param[in] startx x value corresponding to da[0]
876 * \param[in] delx difference in x values for the situation where the
877 * elements of da correspond to the evaluation of a
878 * function at equal intervals of size %delx
879 * \return 0 if OK, 1 on error
880 */
881 l_ok
882 l_dnaSetParameters(L_DNA *da,
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
895 /*!
896 * \brief l_dnaCopyParameters()
897 *
898 * \param[in] dad destination DNuma
899 * \param[in] das source DNuma
900 * \return 0 if OK, 1 on error
901 */
902 l_ok
903 l_dnaCopyParameters(L_DNA *dad,
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 *----------------------------------------------------------------------*/
920 /*!
921 * \brief l_dnaRead()
922 *
923 * \param[in] filename
924 * \return da, or NULL on error
925 */
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_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
947 /*!
948 * \brief l_dnaReadStream()
949 *
950 * \param[in] fp file stream
951 * \return da, or NULL on error
952 *
953 * <pre>
954 * Notes:
955 * (1) fscanf takes %lf to read a double; fprintf takes %f to write it.
956 * (2) It is OK for the dna to be empty.
957 * </pre>
958 */
959 L_DNA *
960 l_dnaReadStream(FILE *fp)
961 {
962 l_int32 i, n, index, ret, version;
963 l_float64 val, startx, delx;
964 L_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
999 /*!
1000 * \brief l_dnaReadMem()
1001 *
1002 * \param[in] data dna serialization; in ascii
1003 * \param[in] size of data; can use strlen to get it
1004 * \return da, or NULL on error
1005 */
1006 L_DNA *
1007 l_dnaReadMem(const l_uint8 *data,
1008 size_t size)
1009 {
1010 FILE *fp;
1011 L_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
1025 /*!
1026 * \brief l_dnaWrite()
1027 *
1028 * \param[in] filename
1029 * \param[in] da
1030 * \return 0 if OK, 1 on error
1031 */
1032 l_ok
1033 l_dnaWrite(const char *filename,
1034 L_DNA *da)
1035 {
1036 l_int32 ret;
1037 FILE *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
1054 /*!
1055 * \brief l_dnaWriteStream()
1056 *
1057 * \param[in] fp file stream; use NULL to write to stderr
1058 * \param[in] da
1059 * \return 0 if OK, 1 on error
1060 */
1061 l_ok
1062 l_dnaWriteStream(FILE *fp,
1063 L_DNA *da)
1064 {
1065 l_int32 i, n;
1066 l_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
1089 /*!
1090 * \brief l_dnaWriteStrderr()
1091 *
1092 * \param[in] da
1093 * \return 0 if OK, 1 on error
1094 */
1095 l_ok
1096 l_dnaWriteStderr(L_DNA *da)
1097 {
1098 l_int32 i, n;
1099 l_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
1120 /*!
1121 * \brief l_dnaWriteMem()
1122 *
1123 * \param[out] pdata data of serialized dna; ascii
1124 * \param[out] psize size of returned data
1125 * \param[in] da
1126 * \return 0 if OK, 1 on error
1127 *
1128 * <pre>
1129 * Notes:
1130 * (1) Serializes a dna in memory and puts the result in a buffer.
1131 * </pre>
1132 */
1133 l_ok
1134 l_dnaWriteMem(l_uint8 **pdata,
1135 size_t *psize,
1136 L_DNA *da)
1137 {
1138 l_int32 ret;
1139 FILE *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 *--------------------------------------------------------------------------*/
1178 /*!
1179 * \brief l_dnaaCreate()
1180 *
1181 * \param[in] n size of l_dna ptr array to be alloc'd 0 for default
1182 * \return daa, or NULL on error
1183 *
1184 */
1185 L_DNAA *
1186 l_dnaaCreate(l_int32 n)
1187 {
1188 L_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
1204 /*!
1205 * \brief l_dnaaCreateFull()
1206 *
1207 * \param[in] nptr size of dna ptr array to be alloc'd
1208 * \param[in] n size of individual dna arrays to be alloc'd 0 for default
1209 * \return daa, or NULL on error
1210 *
1211 * <pre>
1212 * Notes:
1213 * (1) This allocates a dnaa and fills the array with allocated dnas.
1214 * In use, after calling this function, use
1215 * l_dnaaAddNumber(dnaa, index, val);
1216 * to add val to the index-th dna in dnaa.
1217 * </pre>
1218 */
1219 L_DNAA *
1220 l_dnaaCreateFull(l_int32 nptr,
1221 l_int32 n)
1222 {
1223 l_int32 i;
1224 L_DNAA *daa;
1225 L_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
1237 /*!
1238 * \brief l_dnaaTruncate()
1239 *
1240 * \param[in] daa
1241 * \return 0 if OK, 1 on error
1242 *
1243 * <pre>
1244 * Notes:
1245 * (1) This identifies the largest index containing a dna that
1246 * has any numbers within it, destroys all dna beyond that
1247 * index, and resets the count.
1248 * </pre>
1249 */
1250 l_ok
1251 l_dnaaTruncate(L_DNAA *daa)
1252 {
1253 l_int32 i, n, nn;
1254 L_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
1276 /*!
1277 * \brief l_dnaaDestroy()
1278 *
1279 * \param[in,out] pdaa will be set to null before returning
1280 * \return void
1281 */
1282 void
1283 l_dnaaDestroy(L_DNAA **pdaa)
1284 {
1285 l_int32 i;
1286 L_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 *--------------------------------------------------------------------------*/
1307 /*!
1308 * \brief l_dnaaAddDna()
1309 *
1310 * \param[in] daa
1311 * \param[in] da to be added
1312 * \param[in] copyflag L_INSERT, L_COPY, L_CLONE
1313 * \return 0 if OK, 1 on error
1314 */
1315 l_ok
1316 l_dnaaAddDna(L_DNAA *daa,
1317 L_DNA *da,
1318 l_int32 copyflag)
1319 {
1320 l_int32 n;
1321 L_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
1353 /*!
1354 * \brief l_dnaaExtendArray()
1355 *
1356 * \param[in] daa
1357 * \return 0 if OK, 1 on error
1358 *
1359 * <pre>
1360 * Notes:
1361 * (1) Doubles the number of dna ptrs.
1362 * (2) The max size of the dna array is 1M ptrs.
1363 * </pre>
1364 */
1365 static l_int32
1366 l_dnaaExtendArray(L_DNAA *daa)
1367 {
1368 size_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 *----------------------------------------------------------------------*/
1391 /*!
1392 * \brief l_dnaaGetCount()
1393 *
1394 * \param[in] daa
1395 * \return count number of l_dna, or 0 if no l_dna or on error
1396 */
1397 l_int32
1398 l_dnaaGetCount(L_DNAA *daa)
1399 {
1400 if (!daa)
1401 return ERROR_INT("daa not defined", __func__, 0);
1402 return daa->n;
1403 }
1404
1405
1406 /*!
1407 * \brief l_dnaaGetDnaCount()
1408 *
1409 * \param[in] daa
1410 * \param[in] index of l_dna in daa
1411 * \return count of numbers in the referenced l_dna, or 0 on error.
1412 */
1413 l_int32
1414 l_dnaaGetDnaCount(L_DNAA *daa,
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
1425 /*!
1426 * \brief l_dnaaGetNumberCount()
1427 *
1428 * \param[in] daa
1429 * \return count total number of numbers in the l_dnaa,
1430 * or 0 if no numbers or on error
1431 */
1432 l_int32
1433 l_dnaaGetNumberCount(L_DNAA *daa)
1434 {
1435 L_DNA *da;
1436 l_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
1452 /*!
1453 * \brief l_dnaaGetDna()
1454 *
1455 * \param[in] daa
1456 * \param[in] index to the index-th l_dna
1457 * \param[in] accessflag L_COPY or L_CLONE
1458 * \return l_dna, or NULL on error
1459 */
1460 L_DNA *
1461 l_dnaaGetDna(L_DNAA *daa,
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
1479 /*!
1480 * \brief l_dnaaReplaceDna()
1481 *
1482 * \param[in] daa
1483 * \param[in] index to the index-th l_dna
1484 * \param[in] da insert and replace any existing one
1485 * \return 0 if OK, 1 on error
1486 *
1487 * <pre>
1488 * Notes:
1489 * (1) Any existing l_dna is destroyed, and the input one
1490 * is inserted in its place.
1491 * (2) If %index is invalid, return 1 (error)
1492 * </pre>
1493 */
1494 l_ok
1495 l_dnaaReplaceDna(L_DNAA *daa,
1496 l_int32 index,
1497 L_DNA *da)
1498 {
1499 l_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
1515 /*!
1516 * \brief l_dnaaGetValue()
1517 *
1518 * \param[in] daa
1519 * \param[in] i index of l_dna within l_dnaa
1520 * \param[in] j index into l_dna
1521 * \param[out] pval double value
1522 * \return 0 if OK, 1 on error
1523 */
1524 l_ok
1525 l_dnaaGetValue(L_DNAA *daa,
1526 l_int32 i,
1527 l_int32 j,
1528 l_float64 *pval)
1529 {
1530 l_int32 n;
1531 L_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
1549 /*!
1550 * \brief l_dnaaAddNumber()
1551 *
1552 * \param[in] daa
1553 * \param[in] index of l_dna within l_dnaa
1554 * \param[in] val number to be added; stored as a double
1555 * \return 0 if OK, 1 on error
1556 *
1557 * <pre>
1558 * Notes:
1559 * (1) Adds to an existing l_dna only.
1560 * </pre>
1561 */
1562 l_ok
1563 l_dnaaAddNumber(L_DNAA *daa,
1564 l_int32 index,
1565 l_float64 val)
1566 {
1567 l_int32 n;
1568 L_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 *----------------------------------------------------------------------*/
1586 /*!
1587 * \brief l_dnaaRead()
1588 *
1589 * \param[in] filename
1590 * \return daa, or NULL on error
1591 */
1592 L_DNAA *
1593 l_dnaaRead(const char *filename)
1594 {
1595 FILE *fp;
1596 L_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
1613 /*!
1614 * \brief l_dnaaReadStream()
1615 *
1616 * \param[in] fp file stream
1617 * \return daa, or NULL on error
1618 *
1619 * <pre>
1620 * Notes:
1621 * (1) It is OK for the dnaa to be empty.
1622 * </pre>
1623 */
1624 L_DNAA *
1625 l_dnaaReadStream(FILE *fp)
1626 {
1627 l_int32 i, n, index, ret, version;
1628 L_DNA *da;
1629 L_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
1665 /*!
1666 * \brief l_dnaaReadMem()
1667 *
1668 * \param[in] data dnaa serialization; in ascii
1669 * \param[in] size of data; can use strlen to get it
1670 * \return daa, or NULL on error
1671 */
1672 L_DNAA *
1673 l_dnaaReadMem(const l_uint8 *data,
1674 size_t size)
1675 {
1676 FILE *fp;
1677 L_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
1691 /*!
1692 * \brief l_dnaaWrite()
1693 *
1694 * \param[in] filename
1695 * \param[in] daa
1696 * \return 0 if OK, 1 on error
1697 */
1698 l_ok
1699 l_dnaaWrite(const char *filename,
1700 L_DNAA *daa)
1701 {
1702 l_int32 ret;
1703 FILE *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
1720 /*!
1721 * \brief l_dnaaWriteStream()
1722 *
1723 * \param[in] fp file stream
1724 * \param[in] daa
1725 * \return 0 if OK, 1 on error
1726 */
1727 l_ok
1728 l_dnaaWriteStream(FILE *fp,
1729 L_DNAA *daa)
1730 {
1731 l_int32 i, n;
1732 L_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
1754 /*!
1755 * \brief l_dnaaWriteMem()
1756 *
1757 * \param[out] pdata data of serialized dnaa; ascii
1758 * \param[out] psize size of returned data
1759 * \param[in] daa
1760 * \return 0 if OK, 1 on error
1761 *
1762 * <pre>
1763 * Notes:
1764 * (1) Serializes a dnaa in memory and puts the result in a buffer.
1765 * </pre>
1766 */
1767 l_ok
1768 l_dnaaWriteMem(l_uint8 **pdata,
1769 size_t *psize,
1770 L_DNAA *daa)
1771 {
1772 l_int32 ret;
1773 FILE *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