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_dnaGetRefcount()
58  *          l_int32      l_dnaChangeRefcount()
59  *          l_int32      l_dnaGetParameters()
60  *          l_int32      l_dnaSetParameters()
61  *          l_int32      l_dnaCopyParameters()
62  *
63  *      Serialize Dna for I/O
64  *          L_DNA       *l_dnaRead()
65  *          L_DNA       *l_dnaReadStream()
66  *          l_int32      l_dnaWrite()
67  *          l_int32      l_dnaWriteStream()
68  *
69  *      Dnaa creation, destruction
70  *          L_DNAA      *l_dnaaCreate()
71  *          L_DNAA      *l_dnaaCreateFull()
72  *          l_int32      l_dnaaTruncate()
73  *          void        *l_dnaaDestroy()
74  *
75  *      Add Dna to Dnaa
76  *          l_int32      l_dnaaAddDna()
77  *          static l_int32  l_dnaaExtendArray()
78  *
79  *      Dnaa accessors
80  *          l_int32      l_dnaaGetCount()
81  *          l_int32      l_dnaaGetDnaCount()
82  *          l_int32      l_dnaaGetNumberCount()
83  *          L_DNA       *l_dnaaGetDna()
84  *          L_DNA       *l_dnaaReplaceDna()
85  *          l_int32      l_dnaaGetValue()
86  *          l_int32      l_dnaaAddNumber()
87  *
88  *      Serialize Dnaa for I/O
89  *          L_DNAA      *l_dnaaRead()
90  *          L_DNAA      *l_dnaaReadStream()
91  *          l_int32      l_dnaaWrite()
92  *          l_int32      l_dnaaWriteStream()
93  *
94  *    (1) The Dna is a struct holding an array of doubles.  It can also
95  *        be used to store l_int32 values, up to the full precision
96  *        of int32.  Always use it whenever integers larger than a
97  *        few million need to be stored.
98  *
99  *    (2) Always use the accessors in this file, never the fields directly.
100  *
101  *    (3) Storing and retrieving numbers:
102  *
103  *       * to append a new number to the array, use l_dnaAddNumber().  If
104  *         the number is an int, it will will automatically be converted
105  *         to l_float64 and stored.
106  *
107  *       * to reset a value stored in the array, use l_dnaSetValue().
108  *
109  *       * to increment or decrement a value stored in the array,
110  *         use l_dnaShiftValue().
111  *
112  *       * to obtain a value from the array, use either l_dnaGetIValue()
113  *         or l_dnaGetDValue(), depending on whether you are retrieving
114  *         an integer or a float64.  This avoids doing an explicit cast,
115  *         such as
116  *           (a) return a l_float64 and cast it to an l_int32
117  *           (b) cast the return directly to (l_float64 *) to
118  *               satisfy the function prototype, as in
119  *                 l_dnaGetDValue(da, index, (l_float64 *)&ival);   [ugly!]
120  *
121  *    (4) int <--> double conversions:
122  *
123  *        Conversions go automatically from l_int32 --> l_float64,
124  *        without loss of precision.  You must cast (l_int32)
125  *        to go from l_float64 --> l_int32 because you're truncating
126  *        to the integer value.
127  *
128  *    (5) As with other arrays in leptonica, the l_dna has both an allocated
129  *        size and a count of the stored numbers.  When you add a number, it
130  *        goes on the end of the array, and causes a realloc if the array
131  *        is already filled.  However, in situations where you want to
132  *        add numbers randomly into an array, such as when you build a
133  *        histogram, you must set the count of stored numbers in advance.
134  *        This is done with l_dnaSetCount().  If you set a count larger
135  *        than the allocated array, it does a realloc to the size requested.
136  *
137  *    (6) In situations where the data in a l_dna correspond to a function
138  *        y(x), the values can be either at equal spacings in x or at
139  *        arbitrary spacings.  For the former, we can represent all x values
140  *        by two parameters: startx (corresponding to y[0]) and delx
141  *        for the change in x for adjacent values y[i] and y[i+1].
142  *        startx and delx are initialized to 0.0 and 1.0, rsp.
143  *        For arbitrary spacings, we use a second l_dna, and the two
144  *        l_dnas are typically denoted dnay and dnax.
145  * </pre>
146  */
147 
148 #include <string.h>
149 #include <math.h>
150 #include "allheaders.h"
151 
152 static const l_int32 INITIAL_PTR_ARRAYSIZE = 50;      /*!< n'importe quoi */
153 
154     /* Static functions */
155 static l_int32 l_dnaExtendArray(L_DNA *da);
156 static l_int32 l_dnaaExtendArray(L_DNAA *daa);
157 
158 
159 /*--------------------------------------------------------------------------*
160  *                 Dna creation, destruction, copy, clone, etc.             *
161  *--------------------------------------------------------------------------*/
162 /*!
163  * \brief   l_dnaCreate()
164  *
165  * \param[in]    n size of number array to be alloc'd; 0 for default
166  * \return  da, or NULL on error
167  */
168 L_DNA *
l_dnaCreate(l_int32 n)169 l_dnaCreate(l_int32  n)
170 {
171 L_DNA  *da;
172 
173     PROCNAME("l_dnaCreate");
174 
175     if (n <= 0)
176         n = INITIAL_PTR_ARRAYSIZE;
177 
178     da = (L_DNA *)LEPT_CALLOC(1, sizeof(L_DNA));
179     if ((da->array = (l_float64 *)LEPT_CALLOC(n, sizeof(l_float64))) == NULL) {
180         l_dnaDestroy(&da);
181         return (L_DNA *)ERROR_PTR("double array not made", procName, NULL);
182     }
183 
184     da->nalloc = n;
185     da->n = 0;
186     da->refcount = 1;
187     da->startx = 0.0;
188     da->delx = 1.0;
189 
190     return da;
191 }
192 
193 
194 /*!
195  * \brief   l_dnaCreateFromIArray()
196  *
197  * \param[in]    iarray integer
198  * \param[in]    size of the array
199  * \return  da, or NULL on error
200  *
201  * <pre>
202  * Notes:
203  *      (1) We can't insert this int array into the l_dna, because a l_dna
204  *          takes a double array.  So this just copies the data from the
205  *          input array into the l_dna.  The input array continues to be
206  *          owned by the caller.
207  * </pre>
208  */
209 L_DNA *
l_dnaCreateFromIArray(l_int32 * iarray,l_int32 size)210 l_dnaCreateFromIArray(l_int32  *iarray,
211                       l_int32   size)
212 {
213 l_int32  i;
214 L_DNA   *da;
215 
216     PROCNAME("l_dnaCreateFromIArray");
217 
218     if (!iarray)
219         return (L_DNA *)ERROR_PTR("iarray not defined", procName, NULL);
220     if (size <= 0)
221         return (L_DNA *)ERROR_PTR("size must be > 0", procName, NULL);
222 
223     da = l_dnaCreate(size);
224     for (i = 0; i < size; i++)
225         l_dnaAddNumber(da, iarray[i]);
226 
227     return da;
228 }
229 
230 
231 /*!
232  * \brief   l_dnaCreateFromDArray()
233  *
234  * \param[in]    darray float
235  * \param[in]    size of the array
236  * \param[in]    copyflag L_INSERT or L_COPY
237  * \return  da, or NULL on error
238  *
239  * <pre>
240  * Notes:
241  *      (1) With L_INSERT, ownership of the input array is transferred
242  *          to the returned l_dna, and all %size elements are considered
243  *          to be valid.
244  * </pre>
245  */
246 L_DNA *
l_dnaCreateFromDArray(l_float64 * darray,l_int32 size,l_int32 copyflag)247 l_dnaCreateFromDArray(l_float64  *darray,
248                       l_int32     size,
249                       l_int32     copyflag)
250 {
251 l_int32  i;
252 L_DNA   *da;
253 
254     PROCNAME("l_dnaCreateFromDArray");
255 
256     if (!darray)
257         return (L_DNA *)ERROR_PTR("darray not defined", procName, NULL);
258     if (size <= 0)
259         return (L_DNA *)ERROR_PTR("size must be > 0", procName, NULL);
260     if (copyflag != L_INSERT && copyflag != L_COPY)
261         return (L_DNA *)ERROR_PTR("invalid copyflag", procName, NULL);
262 
263     da = l_dnaCreate(size);
264     if (copyflag == L_INSERT) {
265         if (da->array) LEPT_FREE(da->array);
266         da->array = darray;
267         da->n = size;
268     } else {  /* just copy the contents */
269         for (i = 0; i < size; i++)
270             l_dnaAddNumber(da, darray[i]);
271     }
272 
273     return da;
274 }
275 
276 
277 /*!
278  * \brief   l_dnaMakeSequence()
279  *
280  * \param[in]    startval
281  * \param[in]    increment
282  * \param[in]    size of sequence
283  * \return  l_dna of sequence of evenly spaced values, or NULL on error
284  */
285 L_DNA *
l_dnaMakeSequence(l_float64 startval,l_float64 increment,l_int32 size)286 l_dnaMakeSequence(l_float64  startval,
287                   l_float64  increment,
288                   l_int32    size)
289 {
290 l_int32    i;
291 l_float64  val;
292 L_DNA     *da;
293 
294     PROCNAME("l_dnaMakeSequence");
295 
296     if ((da = l_dnaCreate(size)) == NULL)
297         return (L_DNA *)ERROR_PTR("da not made", procName, NULL);
298 
299     for (i = 0; i < size; i++) {
300         val = startval + i * increment;
301         l_dnaAddNumber(da, val);
302     }
303 
304     return da;
305 }
306 
307 
308 /*!
309  * \brief   l_dnaDestroy()
310  *
311  * \param[in,out]   pda to be nulled if it exists
312  * \return  void
313  *
314  * <pre>
315  * Notes:
316  *      (1) Decrements the ref count and, if 0, destroys the l_dna.
317  *      (2) Always nulls the input ptr.
318  * </pre>
319  */
320 void
l_dnaDestroy(L_DNA ** pda)321 l_dnaDestroy(L_DNA  **pda)
322 {
323 L_DNA  *da;
324 
325     PROCNAME("l_dnaDestroy");
326 
327     if (pda == NULL) {
328         L_WARNING("ptr address is NULL\n", procName);
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     l_dnaChangeRefcount(da, -1);
337     if (l_dnaGetRefcount(da) <= 0) {
338         if (da->array)
339             LEPT_FREE(da->array);
340         LEPT_FREE(da);
341     }
342 
343     *pda = NULL;
344     return;
345 }
346 
347 
348 /*!
349  * \brief   l_dnaCopy()
350  *
351  * \param[in]    da
352  * \return  copy of da, or NULL on error
353  *
354  * <pre>
355  * Notes:
356  *      (1) This removes unused ptrs above da->n.
357  * </pre>
358  */
359 L_DNA *
l_dnaCopy(L_DNA * da)360 l_dnaCopy(L_DNA  *da)
361 {
362 l_int32  i;
363 L_DNA   *dac;
364 
365     PROCNAME("l_dnaCopy");
366 
367     if (!da)
368         return (L_DNA *)ERROR_PTR("da not defined", procName, NULL);
369 
370     if ((dac = l_dnaCreate(da->n)) == NULL)
371         return (L_DNA *)ERROR_PTR("dac not made", procName, NULL);
372     dac->startx = da->startx;
373     dac->delx = da->delx;
374 
375     for (i = 0; i < da->n; i++)
376         l_dnaAddNumber(dac, da->array[i]);
377 
378     return dac;
379 }
380 
381 
382 /*!
383  * \brief   l_dnaClone()
384  *
385  * \param[in]    da
386  * \return  ptr to same da, or NULL on error
387  */
388 L_DNA *
l_dnaClone(L_DNA * da)389 l_dnaClone(L_DNA  *da)
390 {
391     PROCNAME("l_dnaClone");
392 
393     if (!da)
394         return (L_DNA *)ERROR_PTR("da not defined", procName, NULL);
395 
396     l_dnaChangeRefcount(da, 1);
397     return da;
398 }
399 
400 
401 /*!
402  * \brief   l_dnaEmpty()
403  *
404  * \param[in]    da
405  * \return  0 if OK; 1 on error
406  *
407  * <pre>
408  * Notes:
409  *      (1) This does not change the allocation of the array.
410  *          It just clears the number of stored numbers, so that
411  *          the array appears to be empty.
412  * </pre>
413  */
414 l_int32
l_dnaEmpty(L_DNA * da)415 l_dnaEmpty(L_DNA  *da)
416 {
417     PROCNAME("l_dnaEmpty");
418 
419     if (!da)
420         return ERROR_INT("da not defined", procName, 1);
421 
422     da->n = 0;
423     return 0;
424 }
425 
426 
427 
428 /*--------------------------------------------------------------------------*
429  *                  Dna: add/remove number and extend array                 *
430  *--------------------------------------------------------------------------*/
431 /*!
432  * \brief   l_dnaAddNumber()
433  *
434  * \param[in]    da
435  * \param[in]    val  float or int to be added; stored as a float
436  * \return  0 if OK, 1 on error
437  */
438 l_int32
l_dnaAddNumber(L_DNA * da,l_float64 val)439 l_dnaAddNumber(L_DNA     *da,
440                l_float64  val)
441 {
442 l_int32  n;
443 
444     PROCNAME("l_dnaAddNumber");
445 
446     if (!da)
447         return ERROR_INT("da not defined", procName, 1);
448 
449     n = l_dnaGetCount(da);
450     if (n >= da->nalloc)
451         l_dnaExtendArray(da);
452     da->array[n] = val;
453     da->n++;
454     return 0;
455 }
456 
457 
458 /*!
459  * \brief   l_dnaExtendArray()
460  *
461  * \param[in]    da
462  * \return  0 if OK, 1 on error
463  */
464 static l_int32
l_dnaExtendArray(L_DNA * da)465 l_dnaExtendArray(L_DNA  *da)
466 {
467     PROCNAME("l_dnaExtendArray");
468 
469     if (!da)
470         return ERROR_INT("da not defined", procName, 1);
471 
472     if ((da->array = (l_float64 *)reallocNew((void **)&da->array,
473                                 sizeof(l_float64) * da->nalloc,
474                                 2 * sizeof(l_float64) * da->nalloc)) == NULL)
475             return ERROR_INT("new ptr array not returned", procName, 1);
476 
477     da->nalloc *= 2;
478     return 0;
479 }
480 
481 
482 /*!
483  * \brief   l_dnaInsertNumber()
484  *
485  * \param[in]    da
486  * \param[in]    index location in da to insert new value
487  * \param[in]    val  float64 or integer to be added
488  * \return  0 if OK, 1 on error
489  *
490  * <pre>
491  * Notes:
492  *      (1) This shifts da[i] --> da[i + 1] for all i >= index,
493  *          and then inserts val as da[index].
494  *      (2) It should not be used repeatedly on large arrays,
495  *          because the function is O(n).
496  *
497  * </pre>
498  */
499 l_int32
l_dnaInsertNumber(L_DNA * da,l_int32 index,l_float64 val)500 l_dnaInsertNumber(L_DNA      *da,
501                   l_int32    index,
502                   l_float64  val)
503 {
504 l_int32  i, n;
505 
506     PROCNAME("l_dnaInsertNumber");
507 
508     if (!da)
509         return ERROR_INT("da not defined", procName, 1);
510     n = l_dnaGetCount(da);
511     if (index < 0 || index > n)
512         return ERROR_INT("index not in {0...n}", procName, 1);
513 
514     if (n >= da->nalloc)
515         l_dnaExtendArray(da);
516     for (i = n; i > index; i--)
517         da->array[i] = da->array[i - 1];
518     da->array[index] = val;
519     da->n++;
520     return 0;
521 }
522 
523 
524 /*!
525  * \brief   l_dnaRemoveNumber()
526  *
527  * \param[in]    da
528  * \param[in]    index element to be removed
529  * \return  0 if OK, 1 on error
530  *
531  * <pre>
532  * Notes:
533  *      (1) This shifts da[i] --> da[i - 1] for all i > index.
534  *      (2) It should not be used repeatedly on large arrays,
535  *          because the function is O(n).
536  * </pre>
537  */
538 l_int32
l_dnaRemoveNumber(L_DNA * da,l_int32 index)539 l_dnaRemoveNumber(L_DNA   *da,
540                   l_int32  index)
541 {
542 l_int32  i, n;
543 
544     PROCNAME("l_dnaRemoveNumber");
545 
546     if (!da)
547         return ERROR_INT("da not defined", procName, 1);
548     n = l_dnaGetCount(da);
549     if (index < 0 || index >= n)
550         return ERROR_INT("index not in {0...n - 1}", procName, 1);
551 
552     for (i = index + 1; i < n; i++)
553         da->array[i - 1] = da->array[i];
554     da->n--;
555     return 0;
556 }
557 
558 
559 /*!
560  * \brief   l_dnaReplaceNumber()
561  *
562  * \param[in]    da
563  * \param[in]    index element to be replaced
564  * \param[in]    val new value to replace old one
565  * \return  0 if OK, 1 on error
566  */
567 l_int32
l_dnaReplaceNumber(L_DNA * da,l_int32 index,l_float64 val)568 l_dnaReplaceNumber(L_DNA     *da,
569                    l_int32    index,
570                    l_float64  val)
571 {
572 l_int32  n;
573 
574     PROCNAME("l_dnaReplaceNumber");
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         return ERROR_INT("index not in {0...n - 1}", procName, 1);
581 
582     da->array[index] = val;
583     return 0;
584 }
585 
586 
587 /*----------------------------------------------------------------------*
588  *                             Dna accessors                            *
589  *----------------------------------------------------------------------*/
590 /*!
591  * \brief   l_dnaGetCount()
592  *
593  * \param[in]    da
594  * \return  count, or 0 if no numbers or on error
595  */
596 l_int32
l_dnaGetCount(L_DNA * da)597 l_dnaGetCount(L_DNA  *da)
598 {
599     PROCNAME("l_dnaGetCount");
600 
601     if (!da)
602         return ERROR_INT("da not defined", procName, 0);
603     return da->n;
604 }
605 
606 
607 /*!
608  * \brief   l_dnaSetCount()
609  *
610  * \param[in]    da
611  * \param[in]    newcount
612  * \return  0 if OK, 1 on error
613  *
614  * <pre>
615  * Notes:
616  *      (1) If newcount <= da->nalloc, this resets da->n.
617  *          Using newcount = 0 is equivalent to l_dnaEmpty().
618  *      (2) If newcount > da->nalloc, this causes a realloc
619  *          to a size da->nalloc = newcount.
620  *      (3) All the previously unused values in da are set to 0.0.
621  * </pre>
622  */
623 l_int32
l_dnaSetCount(L_DNA * da,l_int32 newcount)624 l_dnaSetCount(L_DNA   *da,
625               l_int32  newcount)
626 {
627     PROCNAME("l_dnaSetCount");
628 
629     if (!da)
630         return ERROR_INT("da not defined", procName, 1);
631     if (newcount > da->nalloc) {
632         if ((da->array = (l_float64 *)reallocNew((void **)&da->array,
633                          sizeof(l_float64) * da->nalloc,
634                          sizeof(l_float64) * newcount)) == NULL)
635             return ERROR_INT("new ptr array not returned", procName, 1);
636         da->nalloc = newcount;
637     }
638     da->n = newcount;
639     return 0;
640 }
641 
642 
643 /*!
644  * \brief   l_dnaGetDValue()
645  *
646  * \param[in]    da
647  * \param[in]    index into l_dna
648  * \param[out]   pval  double value; 0.0 on error
649  * \return  0 if OK; 1 on error
650  *
651  * <pre>
652  * Notes:
653  *      (1) Caller may need to check the function return value to
654  *          decide if a 0.0 in the returned ival is valid.
655  * </pre>
656  */
657 l_int32
l_dnaGetDValue(L_DNA * da,l_int32 index,l_float64 * pval)658 l_dnaGetDValue(L_DNA      *da,
659                l_int32     index,
660                l_float64  *pval)
661 {
662     PROCNAME("l_dnaGetDValue");
663 
664     if (!pval)
665         return ERROR_INT("&val not defined", procName, 1);
666     *pval = 0.0;
667     if (!da)
668         return ERROR_INT("da not defined", procName, 1);
669 
670     if (index < 0 || index >= da->n)
671         return ERROR_INT("index not valid", procName, 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_int32
l_dnaGetIValue(L_DNA * da,l_int32 index,l_int32 * pival)693 l_dnaGetIValue(L_DNA    *da,
694                l_int32   index,
695                l_int32  *pival)
696 {
697 l_float64  val;
698 
699     PROCNAME("l_dnaGetIValue");
700 
701     if (!pival)
702         return ERROR_INT("&ival not defined", procName, 1);
703     *pival = 0;
704     if (!da)
705         return ERROR_INT("da not defined", procName, 1);
706 
707     if (index < 0 || index >= da->n)
708         return ERROR_INT("index not valid", procName, 1);
709 
710     val = da->array[index];
711     *pival = (l_int32)(val + L_SIGN(val) * 0.5);
712     return 0;
713 }
714 
715 
716 /*!
717  * \brief   l_dnaSetValue()
718  *
719  * \param[in]    da
720  * \param[in]    index  to element to be set
721  * \param[in]    val  to set element
722  * \return  0 if OK; 1 on error
723  */
724 l_int32
l_dnaSetValue(L_DNA * da,l_int32 index,l_float64 val)725 l_dnaSetValue(L_DNA     *da,
726               l_int32    index,
727               l_float64  val)
728 {
729     PROCNAME("l_dnaSetValue");
730 
731     if (!da)
732         return ERROR_INT("da not defined", procName, 1);
733     if (index < 0 || index >= da->n)
734         return ERROR_INT("index not valid", procName, 1);
735 
736     da->array[index] = val;
737     return 0;
738 }
739 
740 
741 /*!
742  * \brief   l_dnaShiftValue()
743  *
744  * \param[in]    da
745  * \param[in]    index to element to change relative to the current value
746  * \param[in]    diff  increment if diff > 0 or decrement if diff < 0
747  * \return  0 if OK; 1 on error
748  */
749 l_int32
l_dnaShiftValue(L_DNA * da,l_int32 index,l_float64 diff)750 l_dnaShiftValue(L_DNA     *da,
751                 l_int32    index,
752                 l_float64  diff)
753 {
754     PROCNAME("l_dnaShiftValue");
755 
756     if (!da)
757         return ERROR_INT("da not defined", procName, 1);
758     if (index < 0 || index >= da->n)
759         return ERROR_INT("index not valid", procName, 1);
760 
761     da->array[index] += diff;
762     return 0;
763 }
764 
765 
766 /*!
767  * \brief   l_dnaGetIArray()
768  *
769  * \param[in]    da
770  * \return  a copy of the bare internal array, integerized
771  *              by rounding, or NULL on error
772  * <pre>
773  * Notes:
774  *      (1) A copy of the array is made, because we need to
775  *          generate an integer array from the bare double array.
776  *          The caller is responsible for freeing the array.
777  *      (2) The array size is determined by the number of stored numbers,
778  *          not by the size of the allocated array in the l_dna.
779  *      (3) This function is provided to simplify calculations
780  *          using the bare internal array, rather than continually
781  *          calling accessors on the l_dna.  It is typically used
782  *          on an array of size 256.
783  * </pre>
784  */
785 l_int32 *
l_dnaGetIArray(L_DNA * da)786 l_dnaGetIArray(L_DNA  *da)
787 {
788 l_int32   i, n, ival;
789 l_int32  *array;
790 
791     PROCNAME("l_dnaGetIArray");
792 
793     if (!da)
794         return (l_int32 *)ERROR_PTR("da not defined", procName, NULL);
795 
796     n = l_dnaGetCount(da);
797     if ((array = (l_int32 *)LEPT_CALLOC(n, sizeof(l_int32))) == NULL)
798         return (l_int32 *)ERROR_PTR("array not made", procName, NULL);
799     for (i = 0; i < n; i++) {
800         l_dnaGetIValue(da, i, &ival);
801         array[i] = ival;
802     }
803 
804     return array;
805 }
806 
807 
808 /*!
809  * \brief   l_dnaGetDArray()
810  *
811  * \param[in]    da
812  * \param[in]    copyflag L_NOCOPY or L_COPY
813  * \return  either the bare internal array or a copy of it,
814  *              or NULL on error
815  *
816  * <pre>
817  * Notes:
818  *      (1) If copyflag == L_COPY, it makes a copy which the caller
819  *          is responsible for freeing.  Otherwise, it operates
820  *          directly on the bare array of the l_dna.
821  *      (2) Very important: for L_NOCOPY, any writes to the array
822  *          will be in the l_dna.  Do not write beyond the size of
823  *          the count field, because it will not be accessible
824  *          from the l_dna!  If necessary, be sure to set the count
825  *          field to a larger number (such as the alloc size)
826  *          BEFORE calling this function.  Creating with l_dnaMakeConstant()
827  *          is another way to insure full initialization.
828  * </pre>
829  */
830 l_float64 *
l_dnaGetDArray(L_DNA * da,l_int32 copyflag)831 l_dnaGetDArray(L_DNA   *da,
832                l_int32  copyflag)
833 {
834 l_int32     i, n;
835 l_float64  *array;
836 
837     PROCNAME("l_dnaGetDArray");
838 
839     if (!da)
840         return (l_float64 *)ERROR_PTR("da not defined", procName, NULL);
841 
842     if (copyflag == L_NOCOPY) {
843         array = da->array;
844     } else {  /* copyflag == L_COPY */
845         n = l_dnaGetCount(da);
846         if ((array = (l_float64 *)LEPT_CALLOC(n, sizeof(l_float64))) == NULL)
847             return (l_float64 *)ERROR_PTR("array not made", procName, NULL);
848         for (i = 0; i < n; i++)
849             array[i] = da->array[i];
850     }
851 
852     return array;
853 }
854 
855 
856 /*!
857  * \brief   l_dnaGetRefCount()
858  *
859  * \param[in]    da
860  * \return  refcount, or UNDEF on error
861  */
862 l_int32
l_dnaGetRefcount(L_DNA * da)863 l_dnaGetRefcount(L_DNA  *da)
864 {
865     PROCNAME("l_dnaGetRefcount");
866 
867     if (!da)
868         return ERROR_INT("da not defined", procName, UNDEF);
869     return da->refcount;
870 }
871 
872 
873 /*!
874  * \brief   l_dnaChangeRefCount()
875  *
876  * \param[in]    da
877  * \param[in]    delta change to be applied
878  * \return  0 if OK, 1 on error
879  */
880 l_int32
l_dnaChangeRefcount(L_DNA * da,l_int32 delta)881 l_dnaChangeRefcount(L_DNA   *da,
882                     l_int32  delta)
883 {
884     PROCNAME("l_dnaChangeRefcount");
885 
886     if (!da)
887         return ERROR_INT("da not defined", procName, 1);
888     da->refcount += delta;
889     return 0;
890 }
891 
892 
893 /*!
894  * \brief   l_dnaGetParameters()
895  *
896  * \param[in]    da
897  * \param[out]   pstartx [optional] startx
898  * \param[out]   pdelx [optional] delx
899  * \return  0 if OK, 1 on error
900  */
901 l_int32
l_dnaGetParameters(L_DNA * da,l_float64 * pstartx,l_float64 * pdelx)902 l_dnaGetParameters(L_DNA     *da,
903                    l_float64  *pstartx,
904                    l_float64  *pdelx)
905 {
906     PROCNAME("l_dnaGetParameters");
907 
908     if (pstartx) *pstartx = 0.0;
909     if (pdelx) *pdelx = 1.0;
910     if (!pstartx && !pdelx)
911         return ERROR_INT("neither &startx nor &delx are defined", procName, 1);
912     if (!da)
913         return ERROR_INT("da not defined", procName, 1);
914 
915     if (pstartx) *pstartx = da->startx;
916     if (pdelx) *pdelx = da->delx;
917     return 0;
918 }
919 
920 
921 /*!
922  * \brief   l_dnaSetParameters()
923  *
924  * \param[in]    da
925  * \param[in]    startx x value corresponding to da[0]
926  * \param[in]    delx difference in x values for the situation where the
927  *                    elements of da correspond to the evaulation of a
928  *                    function at equal intervals of size %delx
929  * \return  0 if OK, 1 on error
930  */
931 l_int32
l_dnaSetParameters(L_DNA * da,l_float64 startx,l_float64 delx)932 l_dnaSetParameters(L_DNA     *da,
933                    l_float64  startx,
934                    l_float64  delx)
935 {
936     PROCNAME("l_dnaSetParameters");
937 
938     if (!da)
939         return ERROR_INT("da not defined", procName, 1);
940 
941     da->startx = startx;
942     da->delx = delx;
943     return 0;
944 }
945 
946 
947 /*!
948  * \brief   l_dnaCopyParameters()
949  *
950  * \param[in]    dad destination DNuma
951  * \param[in]    das source DNuma
952  * \return  0 if OK, 1 on error
953  */
954 l_int32
l_dnaCopyParameters(L_DNA * dad,L_DNA * das)955 l_dnaCopyParameters(L_DNA  *dad,
956                     L_DNA  *das)
957 {
958 l_float64  start, binsize;
959 
960     PROCNAME("l_dnaCopyParameters");
961 
962     if (!das || !dad)
963         return ERROR_INT("das and dad not both defined", procName, 1);
964 
965     l_dnaGetParameters(das, &start, &binsize);
966     l_dnaSetParameters(dad, start, binsize);
967     return 0;
968 }
969 
970 
971 /*----------------------------------------------------------------------*
972  *                        Serialize Dna for I/O                         *
973  *----------------------------------------------------------------------*/
974 /*!
975  * \brief   l_dnaRead()
976  *
977  * \param[in]    filename
978  * \return  da, or NULL on error
979  */
980 L_DNA *
l_dnaRead(const char * filename)981 l_dnaRead(const char  *filename)
982 {
983 FILE   *fp;
984 L_DNA  *da;
985 
986     PROCNAME("l_dnaRead");
987 
988     if (!filename)
989         return (L_DNA *)ERROR_PTR("filename not defined", procName, NULL);
990 
991     if ((fp = fopenReadStream(filename)) == NULL)
992         return (L_DNA *)ERROR_PTR("stream not opened", procName, NULL);
993     da = l_dnaReadStream(fp);
994     fclose(fp);
995     if (!da)
996         return (L_DNA *)ERROR_PTR("da not read", procName, NULL);
997     return da;
998 }
999 
1000 
1001 /*!
1002  * \brief   l_dnaReadStream()
1003  *
1004  * \param[in]    fp file stream
1005  * \return  da, or NULL on error
1006  *
1007  * <pre>
1008  * Notes:
1009  *      (1) fscanf takes %lf to read a double; fprintf takes %f to write it.
1010  * </pre>
1011  */
1012 L_DNA *
l_dnaReadStream(FILE * fp)1013 l_dnaReadStream(FILE  *fp)
1014 {
1015 l_int32    i, n, index, ret, version;
1016 l_float64  val, startx, delx;
1017 L_DNA     *da;
1018 
1019     PROCNAME("l_dnaReadStream");
1020 
1021     if (!fp)
1022         return (L_DNA *)ERROR_PTR("stream not defined", procName, NULL);
1023 
1024     ret = fscanf(fp, "\nL_Dna Version %d\n", &version);
1025     if (ret != 1)
1026         return (L_DNA *)ERROR_PTR("not a l_dna file", procName, NULL);
1027     if (version != DNA_VERSION_NUMBER)
1028         return (L_DNA *)ERROR_PTR("invalid l_dna version", procName, NULL);
1029     if (fscanf(fp, "Number of numbers = %d\n", &n) != 1)
1030         return (L_DNA *)ERROR_PTR("invalid number of numbers", procName, NULL);
1031 
1032     if ((da = l_dnaCreate(n)) == NULL)
1033         return (L_DNA *)ERROR_PTR("da not made", procName, NULL);
1034     for (i = 0; i < n; i++) {
1035         if (fscanf(fp, "  [%d] = %lf\n", &index, &val) != 2) {
1036             l_dnaDestroy(&da);
1037             return (L_DNA *)ERROR_PTR("bad input data", procName, NULL);
1038         }
1039         l_dnaAddNumber(da, val);
1040     }
1041 
1042         /* Optional data */
1043     if (fscanf(fp, "startx = %lf, delx = %lf\n", &startx, &delx) == 2)
1044         l_dnaSetParameters(da, startx, delx);
1045     return da;
1046 }
1047 
1048 
1049 /*!
1050  * \brief   l_dnaWrite()
1051  *
1052  * \param[in]    filename, da
1053  * \return  0 if OK, 1 on error
1054  */
1055 l_int32
l_dnaWrite(const char * filename,L_DNA * da)1056 l_dnaWrite(const char  *filename,
1057            L_DNA       *da)
1058 {
1059 l_int32  ret;
1060 FILE    *fp;
1061 
1062     PROCNAME("l_dnaWrite");
1063 
1064     if (!filename)
1065         return ERROR_INT("filename not defined", procName, 1);
1066     if (!da)
1067         return ERROR_INT("da not defined", procName, 1);
1068 
1069     if ((fp = fopenWriteStream(filename, "w")) == NULL)
1070         return ERROR_INT("stream not opened", procName, 1);
1071     ret = l_dnaWriteStream(fp, da);
1072     fclose(fp);
1073     if (ret)
1074         return ERROR_INT("da not written to stream", procName, 1);
1075     return 0;
1076 }
1077 
1078 
1079 /*!
1080  * \brief   l_dnaWriteStream()
1081  *
1082  * \param[in]    fp file stream
1083  * \param[in]    da
1084  * \return  0 if OK, 1 on error
1085  */
1086 l_int32
l_dnaWriteStream(FILE * fp,L_DNA * da)1087 l_dnaWriteStream(FILE   *fp,
1088                  L_DNA  *da)
1089 {
1090 l_int32    i, n;
1091 l_float64  startx, delx;
1092 
1093     PROCNAME("l_dnaWriteStream");
1094 
1095     if (!fp)
1096         return ERROR_INT("stream not defined", procName, 1);
1097     if (!da)
1098         return ERROR_INT("da not defined", procName, 1);
1099 
1100     n = l_dnaGetCount(da);
1101     fprintf(fp, "\nL_Dna Version %d\n", DNA_VERSION_NUMBER);
1102     fprintf(fp, "Number of numbers = %d\n", n);
1103     for (i = 0; i < n; i++)
1104         fprintf(fp, "  [%d] = %f\n", i, da->array[i]);
1105     fprintf(fp, "\n");
1106 
1107         /* Optional data */
1108     l_dnaGetParameters(da, &startx, &delx);
1109     if (startx != 0.0 || delx != 1.0)
1110         fprintf(fp, "startx = %f, delx = %f\n", startx, delx);
1111 
1112     return 0;
1113 }
1114 
1115 
1116 /*--------------------------------------------------------------------------*
1117  *                       Dnaa creation, destruction                         *
1118  *--------------------------------------------------------------------------*/
1119 /*!
1120  * \brief   l_dnaaCreate()
1121  *
1122  * \param[in]    n size of l_dna ptr array to be alloc'd 0 for default
1123  * \return  daa, or NULL on error
1124  *
1125  */
1126 L_DNAA *
l_dnaaCreate(l_int32 n)1127 l_dnaaCreate(l_int32  n)
1128 {
1129 L_DNAA  *daa;
1130 
1131     PROCNAME("l_dnaaCreate");
1132 
1133     if (n <= 0)
1134         n = INITIAL_PTR_ARRAYSIZE;
1135 
1136     daa = (L_DNAA *)LEPT_CALLOC(1, sizeof(L_DNAA));
1137     if ((daa->dna = (L_DNA **)LEPT_CALLOC(n, sizeof(L_DNA *))) == NULL) {
1138         l_dnaaDestroy(&daa);
1139         return (L_DNAA *)ERROR_PTR("l_dna ptr array not made", procName, NULL);
1140     }
1141     daa->nalloc = n;
1142     daa->n = 0;
1143     return daa;
1144 }
1145 
1146 
1147 /*!
1148  * \brief   l_dnaaCreateFull()
1149  *
1150  * \param[in]    nptr: size of dna ptr array to be alloc'd
1151  * \param[in]    n: size of individual dna arrays to be alloc'd 0 for default
1152  * \return  daa, or NULL on error
1153  *
1154  * <pre>
1155  * Notes:
1156  *      (1) This allocates a dnaa and fills the array with allocated dnas.
1157  *          In use, after calling this function, use
1158  *              l_dnaaAddNumber(dnaa, index, val);
1159  *          to add val to the index-th dna in dnaa.
1160  * </pre>
1161  */
1162 L_DNAA *
l_dnaaCreateFull(l_int32 nptr,l_int32 n)1163 l_dnaaCreateFull(l_int32  nptr,
1164                  l_int32  n)
1165 {
1166 l_int32  i;
1167 L_DNAA  *daa;
1168 L_DNA   *da;
1169 
1170     daa = l_dnaaCreate(nptr);
1171     for (i = 0; i < nptr; i++) {
1172         da = l_dnaCreate(n);
1173         l_dnaaAddDna(daa, da, L_INSERT);
1174     }
1175 
1176     return daa;
1177 }
1178 
1179 
1180 /*!
1181  * \brief   l_dnaaTruncate()
1182  *
1183  * \param[in]    daa
1184  * \return  0 if OK, 1 on error
1185  *
1186  * <pre>
1187  * Notes:
1188  *      (1) This identifies the largest index containing a dna that
1189  *          has any numbers within it, destroys all dna beyond that
1190  *          index, and resets the count.
1191  * </pre>
1192  */
1193 l_int32
l_dnaaTruncate(L_DNAA * daa)1194 l_dnaaTruncate(L_DNAA  *daa)
1195 {
1196 l_int32  i, n, nn;
1197 L_DNA   *da;
1198 
1199     PROCNAME("l_dnaaTruncate");
1200 
1201     if (!daa)
1202         return ERROR_INT("daa not defined", procName, 1);
1203 
1204     n = l_dnaaGetCount(daa);
1205     for (i = n - 1; i >= 0; i--) {
1206         da = l_dnaaGetDna(daa, i, L_CLONE);
1207         if (!da)
1208             continue;
1209         nn = l_dnaGetCount(da);
1210         l_dnaDestroy(&da);  /* the clone */
1211         if (nn == 0)
1212             l_dnaDestroy(&daa->dna[i]);
1213         else
1214             break;
1215     }
1216     daa->n = i + 1;
1217     return 0;
1218 }
1219 
1220 
1221 /*!
1222  * \brief   l_dnaaDestroy()
1223  *
1224  * \param[in,out] pdaa to be nulled if it exists
1225  * \return  void
1226  */
1227 void
l_dnaaDestroy(L_DNAA ** pdaa)1228 l_dnaaDestroy(L_DNAA  **pdaa)
1229 {
1230 l_int32  i;
1231 L_DNAA  *daa;
1232 
1233     PROCNAME("l_dnaaDestroy");
1234 
1235     if (pdaa == NULL) {
1236         L_WARNING("ptr address is NULL!\n", procName);
1237         return;
1238     }
1239 
1240     if ((daa = *pdaa) == NULL)
1241         return;
1242 
1243     for (i = 0; i < daa->n; i++)
1244         l_dnaDestroy(&daa->dna[i]);
1245     LEPT_FREE(daa->dna);
1246     LEPT_FREE(daa);
1247     *pdaa = NULL;
1248 
1249     return;
1250 }
1251 
1252 
1253 /*--------------------------------------------------------------------------*
1254  *                             Add Dna to Dnaa                              *
1255  *--------------------------------------------------------------------------*/
1256 /*!
1257  * \brief   l_dnaaAddDna()
1258  *
1259  * \param[in]    daa
1260  * \param[in]    da   to be added
1261  * \param[in]    copyflag  L_INSERT, L_COPY, L_CLONE
1262  * \return  0 if OK, 1 on error
1263  */
1264 l_int32
l_dnaaAddDna(L_DNAA * daa,L_DNA * da,l_int32 copyflag)1265 l_dnaaAddDna(L_DNAA  *daa,
1266              L_DNA   *da,
1267              l_int32  copyflag)
1268 {
1269 l_int32  n;
1270 L_DNA   *dac;
1271 
1272     PROCNAME("l_dnaaAddDna");
1273 
1274     if (!daa)
1275         return ERROR_INT("daa not defined", procName, 1);
1276     if (!da)
1277         return ERROR_INT("da not defined", procName, 1);
1278 
1279     if (copyflag == L_INSERT) {
1280         dac = da;
1281     } else if (copyflag == L_COPY) {
1282         if ((dac = l_dnaCopy(da)) == NULL)
1283             return ERROR_INT("dac not made", procName, 1);
1284     } else if (copyflag == L_CLONE) {
1285         dac = l_dnaClone(da);
1286     } else {
1287         return ERROR_INT("invalid copyflag", procName, 1);
1288     }
1289 
1290     n = l_dnaaGetCount(daa);
1291     if (n >= daa->nalloc)
1292         l_dnaaExtendArray(daa);
1293     daa->dna[n] = dac;
1294     daa->n++;
1295     return 0;
1296 }
1297 
1298 
1299 /*!
1300  * \brief   l_dnaaExtendArray()
1301  *
1302  * \param[in]    daa
1303  * \return  0 if OK, 1 on error
1304  */
1305 static l_int32
l_dnaaExtendArray(L_DNAA * daa)1306 l_dnaaExtendArray(L_DNAA  *daa)
1307 {
1308     PROCNAME("l_dnaaExtendArray");
1309 
1310     if (!daa)
1311         return ERROR_INT("daa not defined", procName, 1);
1312 
1313     if ((daa->dna = (L_DNA **)reallocNew((void **)&daa->dna,
1314                               sizeof(L_DNA *) * daa->nalloc,
1315                               2 * sizeof(L_DNA *) * daa->nalloc)) == NULL)
1316             return ERROR_INT("new ptr array not returned", procName, 1);
1317 
1318     daa->nalloc *= 2;
1319     return 0;
1320 }
1321 
1322 
1323 /*----------------------------------------------------------------------*
1324  *                           DNumaa accessors                           *
1325  *----------------------------------------------------------------------*/
1326 /*!
1327  * \brief   l_dnaaGetCount()
1328  *
1329  * \param[in]    daa
1330  * \return  count number of l_dna, or 0 if no l_dna or on error
1331  */
1332 l_int32
l_dnaaGetCount(L_DNAA * daa)1333 l_dnaaGetCount(L_DNAA  *daa)
1334 {
1335     PROCNAME("l_dnaaGetCount");
1336 
1337     if (!daa)
1338         return ERROR_INT("daa not defined", procName, 0);
1339     return daa->n;
1340 }
1341 
1342 
1343 /*!
1344  * \brief   l_dnaaGetDnaCount()
1345  *
1346  * \param[in]    daa
1347  * \param[in]    index of l_dna in daa
1348  * \return  count of numbers in the referenced l_dna, or 0 on error.
1349  */
1350 l_int32
l_dnaaGetDnaCount(L_DNAA * daa,l_int32 index)1351 l_dnaaGetDnaCount(L_DNAA   *daa,
1352                     l_int32  index)
1353 {
1354     PROCNAME("l_dnaaGetDnaCount");
1355 
1356     if (!daa)
1357         return ERROR_INT("daa not defined", procName, 0);
1358     if (index < 0 || index >= daa->n)
1359         return ERROR_INT("invalid index into daa", procName, 0);
1360     return l_dnaGetCount(daa->dna[index]);
1361 }
1362 
1363 
1364 /*!
1365  * \brief   l_dnaaGetNumberCount()
1366  *
1367  * \param[in]    daa
1368  * \return  count total number of numbers in the l_dnaa,
1369  *                     or 0 if no numbers or on error
1370  */
1371 l_int32
l_dnaaGetNumberCount(L_DNAA * daa)1372 l_dnaaGetNumberCount(L_DNAA  *daa)
1373 {
1374 L_DNA   *da;
1375 l_int32  n, sum, i;
1376 
1377     PROCNAME("l_dnaaGetNumberCount");
1378 
1379     if (!daa)
1380         return ERROR_INT("daa not defined", procName, 0);
1381 
1382     n = l_dnaaGetCount(daa);
1383     for (sum = 0, i = 0; i < n; i++) {
1384         da = l_dnaaGetDna(daa, i, L_CLONE);
1385         sum += l_dnaGetCount(da);
1386         l_dnaDestroy(&da);
1387     }
1388 
1389     return sum;
1390 }
1391 
1392 
1393 /*!
1394  * \brief   l_dnaaGetDna()
1395  *
1396  * \param[in]    daa
1397  * \param[in]    index  to the index-th l_dna
1398  * \param[in]    accessflag   L_COPY or L_CLONE
1399  * \return  l_dna, or NULL on error
1400  */
1401 L_DNA *
l_dnaaGetDna(L_DNAA * daa,l_int32 index,l_int32 accessflag)1402 l_dnaaGetDna(L_DNAA  *daa,
1403              l_int32  index,
1404              l_int32  accessflag)
1405 {
1406     PROCNAME("l_dnaaGetDna");
1407 
1408     if (!daa)
1409         return (L_DNA *)ERROR_PTR("daa not defined", procName, NULL);
1410     if (index < 0 || index >= daa->n)
1411         return (L_DNA *)ERROR_PTR("index not valid", procName, NULL);
1412 
1413     if (accessflag == L_COPY)
1414         return l_dnaCopy(daa->dna[index]);
1415     else if (accessflag == L_CLONE)
1416         return l_dnaClone(daa->dna[index]);
1417     else
1418         return (L_DNA *)ERROR_PTR("invalid accessflag", procName, NULL);
1419 }
1420 
1421 
1422 /*!
1423  * \brief   l_dnaaReplaceDna()
1424  *
1425  * \param[in]    daa
1426  * \param[in]    index  to the index-th l_dna
1427  * \param[in]    da insert and replace any existing one
1428  * \return  0 if OK, 1 on error
1429  *
1430  * <pre>
1431  * Notes:
1432  *      (1) Any existing l_dna is destroyed, and the input one
1433  *          is inserted in its place.
1434  *      (2) If the index is invalid, return 1 (error)
1435  * </pre>
1436  */
1437 l_int32
l_dnaaReplaceDna(L_DNAA * daa,l_int32 index,L_DNA * da)1438 l_dnaaReplaceDna(L_DNAA  *daa,
1439                  l_int32  index,
1440                  L_DNA   *da)
1441 {
1442 l_int32  n;
1443 
1444     PROCNAME("l_dnaaReplaceDna");
1445 
1446     if (!daa)
1447         return ERROR_INT("daa not defined", procName, 1);
1448     if (!da)
1449         return ERROR_INT("da not defined", procName, 1);
1450     n = l_dnaaGetCount(daa);
1451     if (index < 0 || index >= n)
1452         return ERROR_INT("index not valid", procName, 1);
1453 
1454     l_dnaDestroy(&daa->dna[index]);
1455     daa->dna[index] = da;
1456     return 0;
1457 }
1458 
1459 
1460 /*!
1461  * \brief   l_dnaaGetValue()
1462  *
1463  * \param[in]    daa
1464  * \param[in]    i index of l_dna within l_dnaa
1465  * \param[in]    j index into l_dna
1466  * \param[out]   pval double value
1467  * \return  0 if OK, 1 on error
1468  */
1469 l_int32
l_dnaaGetValue(L_DNAA * daa,l_int32 i,l_int32 j,l_float64 * pval)1470 l_dnaaGetValue(L_DNAA     *daa,
1471                l_int32     i,
1472                l_int32     j,
1473                l_float64  *pval)
1474 {
1475 l_int32  n;
1476 L_DNA   *da;
1477 
1478     PROCNAME("l_dnaaGetValue");
1479 
1480     if (!pval)
1481         return ERROR_INT("&val not defined", procName, 1);
1482     *pval = 0.0;
1483     if (!daa)
1484         return ERROR_INT("daa not defined", procName, 1);
1485     n = l_dnaaGetCount(daa);
1486     if (i < 0 || i >= n)
1487         return ERROR_INT("invalid index into daa", procName, 1);
1488     da = daa->dna[i];
1489     if (j < 0 || j >= da->n)
1490         return ERROR_INT("invalid index into da", procName, 1);
1491     *pval = da->array[j];
1492     return 0;
1493 }
1494 
1495 
1496 /*!
1497  * \brief   l_dnaaAddNumber()
1498  *
1499  * \param[in]    daa
1500  * \param[in]    index of l_dna within l_dnaa
1501  * \param[in]    val  number to be added; stored as a double
1502  * \return  0 if OK, 1 on error
1503  *
1504  * <pre>
1505  * Notes:
1506  *      (1) Adds to an existing l_dna only.
1507  * </pre>
1508  */
1509 l_int32
l_dnaaAddNumber(L_DNAA * daa,l_int32 index,l_float64 val)1510 l_dnaaAddNumber(L_DNAA    *daa,
1511                 l_int32    index,
1512                 l_float64  val)
1513 {
1514 l_int32  n;
1515 L_DNA   *da;
1516 
1517     PROCNAME("l_dnaaAddNumber");
1518 
1519     if (!daa)
1520         return ERROR_INT("daa not defined", procName, 1);
1521     n = l_dnaaGetCount(daa);
1522     if (index < 0 || index >= n)
1523         return ERROR_INT("invalid index in daa", procName, 1);
1524 
1525     da = l_dnaaGetDna(daa, index, L_CLONE);
1526     l_dnaAddNumber(da, val);
1527     l_dnaDestroy(&da);
1528     return 0;
1529 }
1530 
1531 
1532 /*----------------------------------------------------------------------*
1533  *                        Serialize Dna for I/O                         *
1534  *----------------------------------------------------------------------*/
1535 /*!
1536  * \brief   l_dnaaRead()
1537  *
1538  * \param[in]    filename
1539  * \return  daa, or NULL on error
1540  */
1541 L_DNAA *
l_dnaaRead(const char * filename)1542 l_dnaaRead(const char  *filename)
1543 {
1544 FILE    *fp;
1545 L_DNAA  *daa;
1546 
1547     PROCNAME("l_dnaaRead");
1548 
1549     if (!filename)
1550         return (L_DNAA *)ERROR_PTR("filename not defined", procName, NULL);
1551 
1552     if ((fp = fopenReadStream(filename)) == NULL)
1553         return (L_DNAA *)ERROR_PTR("stream not opened", procName, NULL);
1554     daa = l_dnaaReadStream(fp);
1555     fclose(fp);
1556     if (!daa)
1557         return (L_DNAA *)ERROR_PTR("daa not read", procName, NULL);
1558     return daa;
1559 }
1560 
1561 
1562 /*!
1563  * \brief   l_dnaaReadStream()
1564  *
1565  * \param[in]    fp file stream
1566  * \return  daa, or NULL on error
1567  */
1568 L_DNAA *
l_dnaaReadStream(FILE * fp)1569 l_dnaaReadStream(FILE  *fp)
1570 {
1571 l_int32    i, n, index, ret, version;
1572 L_DNA     *da;
1573 L_DNAA    *daa;
1574 
1575     PROCNAME("l_dnaaReadStream");
1576 
1577     if (!fp)
1578         return (L_DNAA *)ERROR_PTR("stream not defined", procName, NULL);
1579 
1580     ret = fscanf(fp, "\nL_Dnaa Version %d\n", &version);
1581     if (ret != 1)
1582         return (L_DNAA *)ERROR_PTR("not a l_dna file", procName, NULL);
1583     if (version != DNA_VERSION_NUMBER)
1584         return (L_DNAA *)ERROR_PTR("invalid l_dnaa version", procName, NULL);
1585     if (fscanf(fp, "Number of L_Dna = %d\n\n", &n) != 1)
1586         return (L_DNAA *)ERROR_PTR("invalid number of l_dna", procName, NULL);
1587     if ((daa = l_dnaaCreate(n)) == NULL)
1588         return (L_DNAA *)ERROR_PTR("daa not made", procName, NULL);
1589 
1590     for (i = 0; i < n; i++) {
1591         if (fscanf(fp, "L_Dna[%d]:", &index) != 1) {
1592             l_dnaaDestroy(&daa);
1593             return (L_DNAA *)ERROR_PTR("invalid l_dna header", procName, NULL);
1594         }
1595         if ((da = l_dnaReadStream(fp)) == NULL) {
1596             l_dnaaDestroy(&daa);
1597             return (L_DNAA *)ERROR_PTR("da not made", procName, NULL);
1598         }
1599         l_dnaaAddDna(daa, da, L_INSERT);
1600     }
1601 
1602     return daa;
1603 }
1604 
1605 
1606 /*!
1607  * \brief   l_dnaaWrite()
1608  *
1609  * \param[in]    filename, daa
1610  * \return  0 if OK, 1 on error
1611  */
1612 l_int32
l_dnaaWrite(const char * filename,L_DNAA * daa)1613 l_dnaaWrite(const char  *filename,
1614             L_DNAA      *daa)
1615 {
1616 l_int32  ret;
1617 FILE    *fp;
1618 
1619     PROCNAME("l_dnaaWrite");
1620 
1621     if (!filename)
1622         return ERROR_INT("filename not defined", procName, 1);
1623     if (!daa)
1624         return ERROR_INT("daa not defined", procName, 1);
1625 
1626     if ((fp = fopenWriteStream(filename, "w")) == NULL)
1627         return ERROR_INT("stream not opened", procName, 1);
1628     ret = l_dnaaWriteStream(fp, daa);
1629     fclose(fp);
1630     if (ret)
1631         return ERROR_INT("daa not written to stream", procName, 1);
1632     return 0;
1633 }
1634 
1635 
1636 /*!
1637  * \brief   l_dnaaWriteStream()
1638  *
1639  * \param[in]    fp file stream
1640  * \param[in]    daa
1641  * \return  0 if OK, 1 on error
1642  */
1643 l_int32
l_dnaaWriteStream(FILE * fp,L_DNAA * daa)1644 l_dnaaWriteStream(FILE    *fp,
1645                   L_DNAA  *daa)
1646 {
1647 l_int32  i, n;
1648 L_DNA   *da;
1649 
1650     PROCNAME("l_dnaaWriteStream");
1651 
1652     if (!fp)
1653         return ERROR_INT("stream not defined", procName, 1);
1654     if (!daa)
1655         return ERROR_INT("daa not defined", procName, 1);
1656 
1657     n = l_dnaaGetCount(daa);
1658     fprintf(fp, "\nL_Dnaa Version %d\n", DNA_VERSION_NUMBER);
1659     fprintf(fp, "Number of L_Dna = %d\n\n", n);
1660     for (i = 0; i < n; i++) {
1661         if ((da = l_dnaaGetDna(daa, i, L_CLONE)) == NULL)
1662             return ERROR_INT("da not found", procName, 1);
1663         fprintf(fp, "L_Dna[%d]:", i);
1664         l_dnaWriteStream(fp, da);
1665         l_dnaDestroy(&da);
1666     }
1667 
1668     return 0;
1669 }
1670 
1671