1 /*
2   Teem: Tools to process and visualize scientific data and images             .
3   Copyright (C) 2012, 2011, 2010, 2009  University of Chicago
4   Copyright (C) 2008, 2007, 2006, 2005  Gordon Kindlmann
5   Copyright (C) 2004, 2003, 2002, 2001, 2000, 1999, 1998  University of Utah
6 
7   This library is free software; you can redistribute it and/or
8   modify it under the terms of the GNU Lesser General Public License
9   (LGPL) as published by the Free Software Foundation; either
10   version 2.1 of the License, or (at your option) any later version.
11   The terms of redistributing and/or modifying this software also
12   include exceptions to the LGPL that facilitate static linking.
13 
14   This library is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17   Lesser General Public License for more details.
18 
19   You should have received a copy of the GNU Lesser General Public License
20   along with this library; if not, write to Free Software Foundation, Inc.,
21   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 */
23 
24 #include "ten.h"
25 #include "privateTen.h"
26 
27 /*
28 ******** tendCmdList[]
29 **
30 ** NULL-terminated array of unrrduCmd pointers, as ordered by
31 ** TEN_MAP macro
32 */
33 unrrduCmd *
34 tendCmdList[] = {
35   TEND_MAP(TEND_LIST)
36   NULL
37 };
38 
39 const char *tendTitle = "tend: Diffusion Image Processing and Analysis";
40 
41 /*
42 ******** tendFiberStopParse
43 **
44 ** for parsing the different ways in which a fiber should be stopped
45 ** For the sake of laziness and uniformity, the stop information is
46 ** stored in an array of 3 (three) doubles:
47 ** info[0]: int value from tenFiberStop* enum
48 ** info[1]: 1st parameter associated with stop method (always used)
49 ** info[2]: 2nd parameter, used occasionally
50 */
51 int
tendFiberStopParse(void * ptr,char * _str,char err[AIR_STRLEN_HUGE])52 tendFiberStopParse(void *ptr, char *_str, char err[AIR_STRLEN_HUGE]) {
53   char me[]="tenFiberStopParse", *str, *opt, *opt2;
54   double *info;
55   airArray *mop;
56   int integer;
57 
58   if (!(ptr && _str)) {
59     sprintf(err, "%s: got NULL pointer", me);
60     return 1;
61   }
62   info = (double *)ptr;
63 
64   mop = airMopNew();
65   str = airStrdup(_str);
66   airMopMem(mop, &str, airMopAlways);
67   opt = strchr(str, ':');
68   if (!opt) {
69     /* couldn't parse string as nrrdEncoding, but there wasn't a colon */
70     sprintf(err, "%s: didn't see a colon in \"%s\"", me, str);
71     airMopError(mop); return 1;
72   }
73   *opt = '\0';
74   opt++;
75   info[0] = AIR_CAST(int, airEnumVal(tenFiberStop, str));
76   if (tenFiberStopUnknown == AIR_CAST(int, info[0])) {
77     sprintf(err, "%s: didn't recognize \"%s\" as %s",
78             me, str, tenFiberStop->name);
79     airMopError(mop); return 1;
80   }
81   switch(AIR_CAST(int, info[0])) {
82   case tenFiberStopAniso:
83     /* <aniso>,<level> : tenAniso,double */
84     opt2 = strchr(opt, ',');
85     if (!opt2) {
86       sprintf(err, "%s: didn't see comma between aniso and level in \"%s\"",
87               me, opt);
88       airMopError(mop); return 1;
89     }
90     *opt2 = '\0';
91     opt2++;
92     info[1] = AIR_CAST(int, airEnumVal(tenAniso, opt));
93     if (tenAnisoUnknown == AIR_CAST(int, info[1])) {
94       sprintf(err, "%s: didn't recognize \"%s\" as %s",
95               me, opt, tenAniso->name);
96       airMopError(mop); return 1;
97     }
98     if (1 != sscanf(opt2, "%lg", info+2)) {
99       sprintf(err, "%s: couldn't parse aniso level \"%s\" as double",
100               me, opt2);
101       airMopError(mop); return 1;
102     }
103     /*
104     fprintf(stderr, "!%s: parsed aniso:%s,%g\n", me,
105             airEnumStr(tenAniso, AIR_CAST(int, info[1])), info[2]);
106     */
107     break;
108   case tenFiberStopFraction:
109   case tenFiberStopLength:
110   case tenFiberStopRadius:
111   case tenFiberStopConfidence:
112   case tenFiberStopMinLength:
113     /* all of these take a single double */
114     if (1 != sscanf(opt, "%lg", info+1)) {
115       sprintf(err, "%s: couldn't parse %s \"%s\" as double", me,
116               airEnumStr(tenFiberStop, AIR_CAST(int, info[0])), opt);
117       airMopError(mop); return 1;
118     }
119     /*
120     fprintf(stderr, "!%s: parse %s:%g\n", me,
121             airEnumStr(tenFiberStop, AIR_CAST(int, info[0])),
122             info[1]);
123     */
124     break;
125   case tenFiberStopNumSteps:
126   case tenFiberStopMinNumSteps:
127     /* <#steps> : int */
128     if (1 != sscanf(opt, "%d", &integer)) {
129       sprintf(err, "%s: couldn't parse \"%s\" as int", me, opt);
130       airMopError(mop); return 1;
131     }
132     info[1] = integer;
133     /* fprintf(stderr, "!%s: parse steps:%d\n", me, integer); */
134     break;
135   case tenFiberStopBounds:
136     /* moron */
137     break;
138   default:
139     sprintf(err, "%s: stop method %d not supported", me,
140             AIR_CAST(int, info[0]));
141     airMopError(mop); return 1;
142     break;
143   }
144   airMopOkay(mop);
145   return 0;
146 }
147 
148 hestCB
149 _tendFiberStopCB = {
150   3*sizeof(double),
151   "fiber stop",
152   tendFiberStopParse,
153   NULL
154 };
155 
156 hestCB *
157 tendFiberStopCB = &_tendFiberStopCB;
158