GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/unrrdu/3op.c Lines: 19 48 39.6 %
Date: 2017-05-26 Branches: 1 42 2.4 %

Line Branch Exec Source
1
/*
2
  Teem: Tools to process and visualize scientific data and images             .
3
  Copyright (C) 2013, 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 "unrrdu.h"
25
#include "privateUnrrdu.h"
26
27
#define INFO "Ternary operation on three nrrds or constants"
28
static const char *_unrrdu_3opInfoL =
29
(INFO
30
 ". Can have one, two, or three nrrds, but not zero. "
31
 "Use \"-\" for an operand to signify "
32
 "a nrrd to be read from stdin (a pipe).  Note, however, "
33
 "that \"-\" can probably only be used once (reliably).\n "
34
 "* Uses nrrdArithIterTernaryOp or (with -w) nrrdArithIterTernaryOpSelect");
35
36
int
37
unrrdu_3opMain(int argc, const char **argv, const char *me,
38
               hestParm *hparm) {
39
2
  hestOpt *opt = NULL;
40
1
  char *out, *err;
41
1
  NrrdIter *in1, *in2, *in3;
42
  Nrrd *nout, *ntmp=NULL;
43
1
  int op, type, E, pret, which;
44
  airArray *mop;
45
46
1
  hestOptAdd(&opt, NULL, "operator", airTypeEnum, 1, 1, &op, NULL,
47
             "Ternary operator. Possibilities include:\n "
48
             "\b\bo \"+\", \"x\": sum or product of three values\n "
49
             "\b\bo \"min\", \"max\": minimum, maximum\n "
50
             "\b\bo \"min_sm\": smoothed minimum function; "
51
             "min_sm(x, w, M) is like min(x,M) but for x > M-w (with w > 0) "
52
             "there is a smooth transition from x to asymptotic to M\n "
53
             "\b\bo \"max_sm\": smoothed maximum function; "
54
             "max_sm(M, w, x) is like max(M,x) but for x < m+w (with w > m) "
55
             "there is a smooth transition from x to asymptotic to m\n "
56
             "\b\bo \"lt_sm\": 1st less than 3rd, smoothed by 2nd\n "
57
             "\b\bo \"gt_sm\": 1st greater than 3rd, smoothed by 2nd\n "
58
             "\b\bo \"clamp\": 2nd value is clamped to range between "
59
             "the 1st and the 3rd\n "
60
             "\b\bo \"ifelse\": if 1st value non-zero, then 2nd value, else "
61
             "3rd value\n "
62
             "\b\bo \"lerp\": linear interpolation between the 2nd and "
63
             "3rd values, as the 1st value varies between 0.0 and 1.0, "
64
             "respectively\n "
65
             "\b\bo \"exists\": if the 1st value exists, use the 2nd "
66
             "value, otherwise use the 3rd\n "
67
             "\b\bo \"in_op\": 1 iff 2nd value is > 1st and < 3rd, "
68
             "0 otherwise\n "
69
             "\b\bo \"in_cl\": 1 iff 2nd value is >= 1st and <= 3rd, "
70
             "0 otherwise\n "
71
             "\b\bo \"gauss\": evaluate (at 1st value) Gaussian with mean=2nd "
72
             "and stdv=3rd value\n "
73
             "\b\bo \"rician\": evaluate (at 1st value) Rician with mean=2nd "
74
             "and stdv=3rd value",
75
1
             NULL, nrrdTernaryOp);
76
1
  hestOptAdd(&opt, NULL, "in1", airTypeOther, 1, 1, &in1, NULL,
77
             "First input.  Can be a single value or a nrrd.",
78
1
             NULL, NULL, nrrdHestIter);
79
1
  hestOptAdd(&opt, NULL, "in2", airTypeOther, 1, 1, &in2, NULL,
80
             "Second input.  Can be a single value or a nrrd.",
81
1
             NULL, NULL, nrrdHestIter);
82
1
  hestOptAdd(&opt, NULL, "in3", airTypeOther, 1, 1, &in3, NULL,
83
             "Third input.  Can be a single value or a nrrd.",
84
1
             NULL, NULL, nrrdHestIter);
85
1
  hestOptAdd(&opt, "t,type", "type", airTypeOther, 1, 1, &type, "default",
86
             "type to convert all nrrd inputs to, prior to "
87
             "doing operation.  This also determines output type. "
88
             "By default (not using this option), the types of the input "
89
             "nrrds are left unchanged.",
90
             NULL, NULL, &unrrduHestMaybeTypeCB);
91
1
  hestOptAdd(&opt, "w,which", "arg", airTypeInt, 1, 1, &which, "-1",
92
             "Which argument (0, 1, or 2) should be used to determine the "
93
             "shape of the output nrrd. By default (not using this option), "
94
             "the first non-constant argument is used. ");
95
1
  OPT_ADD_NOUT(out, "output nrrd");
96
97
1
  mop = airMopNew();
98
1
  airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways);
99
100
2
  USAGE(_unrrdu_3opInfoL);
101
  PARSE();
102
  airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways);
103
104
  nout = nrrdNew();
105
  airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways);
106
107
  /*
108
  fprintf(stderr, "%s: op = %d\n", me, op);
109
  fprintf(stderr, "%s: in1->left = %d, in2->left = %d\n", me,
110
          (int)(in1->left), (int)(in2->left));
111
  */
112
  if (nrrdTypeDefault != type) {
113
    /* they wanted to convert nrrds to some other type first */
114
    E = 0;
115
    if (in1->ownNrrd) {
116
      if (!E) E |= nrrdConvert(ntmp=nrrdNew(), in1->ownNrrd, type);
117
      if (!E) nrrdIterSetOwnNrrd(in1, ntmp);
118
    }
119
    if (in2->ownNrrd) {
120
      if (!E) E |= nrrdConvert(ntmp=nrrdNew(), in2->ownNrrd, type);
121
      if (!E) nrrdIterSetOwnNrrd(in2, ntmp);
122
    }
123
    if (in3->ownNrrd) {
124
      if (!E) E |= nrrdConvert(ntmp=nrrdNew(), in3->ownNrrd, type);
125
      if (!E) nrrdIterSetOwnNrrd(in3, ntmp);
126
    }
127
    if (E) {
128
      airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways);
129
      fprintf(stderr, "%s: error converting input nrrd(s):\n%s", me, err);
130
      airMopError(mop);
131
      return 1;
132
    }
133
    /* this will still leave a nrrd in the NrrdIter for nrrdIterNix()
134
       (called by hestParseFree() called be airMopOkay()) to clear up */
135
  }
136
137
  /* HEY: will need to add handling of RNG seed (as in 1op and 2op)
138
     if there are any 3ops involving random numbers */
139
140
  if (-1 == which
141
      ? nrrdArithIterTernaryOp(nout, op, in1, in2, in3)
142
      : nrrdArithIterTernaryOpSelect(nout, op, in1, in2, in3,
143
                                     AIR_CAST(unsigned int, which))) {
144
    airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways);
145
    fprintf(stderr, "%s: error doing ternary operation:\n%s", me, err);
146
    airMopError(mop);
147
    return 1;
148
  }
149
150
  SAVE(out, nout, NULL);
151
152
  airMopOkay(mop);
153
  return 0;
154
1
}
155
156
UNRRDU_CMD(3op, INFO);
157