Bug Summary

File:src/mite/txf.c
Location:line 514, column 7
Description:Branch condition evaluates to a garbage value

Annotated Source Code

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/* learned: don't confuse allocate an array of structs with an array
25 of pointers to structs. Don't be surprised when you bus error
26 because of the difference
27*/
28
29#include "mite.h"
30#include "privateMite.h"
31
32char
33miteRangeChar[MITE_RANGE_NUM9+1] = "ARGBEadsp";
34
35const char *
36_miteStageOpStr[] = {
37 "(unknown miteStageOp)",
38 "min",
39 "max",
40 "add",
41 "multiply"
42};
43
44const int
45_miteStageOpVal[] = {
46 miteStageOpUnknown,
47 miteStageOpMin,
48 miteStageOpMax,
49 miteStageOpAdd,
50 miteStageOpMultiply
51};
52
53const char *
54_miteStageOpStrEqv[] = {
55 "min",
56 "max",
57 "add", "+",
58 "multiply", "*", "x",
59 ""
60};
61
62const int
63_miteStageOpValEqv[] = {
64 miteStageOpMin,
65 miteStageOpMax,
66 miteStageOpAdd, miteStageOpAdd,
67 miteStageOpMultiply, miteStageOpMultiply, miteStageOpMultiply
68};
69
70const airEnum
71_miteStageOp = {
72 "miteStageOp",
73 MITE_STAGE_OP_MAX4,
74 _miteStageOpStr, _miteStageOpVal,
75 NULL((void*)0),
76 _miteStageOpStrEqv, _miteStageOpValEqv,
77 AIR_FALSE0
78};
79const airEnum *const
80miteStageOp = &_miteStageOp;
81
82/*
83******** miteVariableParse()
84**
85** takes a string (usually the label from a nrrd axis) and parses it
86** to determine the gageItemSpec from it (which means finding the
87** kind and item). The valid formats are:
88**
89** "" : NULL kind, 0 item
90** <item> : miteValGageKind (DEPRECATED)
91** mite(<item>) : miteValGageKind
92** gage(<item>) : gageKindScl (DEPRECATED)
93** gage(scalar:<item>) : gageKindScl
94** gage(vector:<item>) : gageKindVec
95** gage(tensor:<item>) : tenGageKind
96**
97** Notice that "scalar", "vector", and "tensor" do NOT refer to the type
98** of the quantity being measured, but rather to the type of volume in
99** which quantity is measured (i.e., the gageKind used)
100*/
101int
102miteVariableParse(gageItemSpec *isp, const char *label) {
103 static const char me[]="miteVariableParse";
104
105 char *buff, *endparen, *kqstr, *col, *kstr, *qstr;
106 airArray *mop;
107
108 if (!( isp && label )) {
5
Taking false branch
109 biffAddf(MITEmiteBiffKey, "%s: got NULL pointer", me);
110 return 1;
111 }
112 if (0 == strlen(label)) {
6
Taking false branch
113 /* nothing was specified; we try to indicate that by mimicking
114 the return of gageItemSpecNew() */
115 isp->item = 0;
116 isp->kind = NULL((void*)0);
117 return 0;
118 }
119 /* else given string was non-empty */
120 mop = airMopNew();
121 buff = airStrdup(label);
122 if (!buff) {
7
Assuming 'buff' is non-null
8
Taking false branch
123 biffAddf(MITEmiteBiffKey, "%s: couldn't strdup label!", me);
124 airMopError(mop); return 1;
125 }
126 airMopAdd(mop, buff, airFree, airMopAlways);
127 if (strstr(buff, "gage(") == buff) {
9
Taking false branch
128 /* txf domain variable is to be measured directly by gage */
129 if (!(endparen = strstr(buff, ")"))) {
130 biffAddf(MITEmiteBiffKey, "%s: didn't see close paren after \"gage(\"", me);
131 airMopError(mop); return 1;
132 }
133 *endparen = 0;
134 kqstr = buff + strlen("gage(");
135 /* first see if its a (deprecated) gageKindScl specification */
136 isp->item = airEnumVal(gageScl, kqstr);
137 if (0 != isp->item) {
138 isp->kind = gageKindScl;
139 fprintf(stderr__stderrp, "\n%s: WARNING: deprecated use of txf domain "
140 "\"gage(%s)\" without explicit gage kind specification; "
141 "should use \"gage(%s:%s)\" instead\n\n",
142 me, kqstr, gageKindScl->name, kqstr);
143 } else {
144 /* should be of form "<kind>:<item>" */
145 col = strstr(kqstr, ":");
146 if (!col) {
147 biffAddf(MITEmiteBiffKey, "%s: didn't see \":\" separator between gage "
148 "kind and item", me);
149 airMopError(mop); return 1;
150 }
151 *col = 0;
152 kstr = kqstr;
153 qstr = col+1;
154 if (!strcmp(gageKindScl->name, kstr)) {
155 isp->kind = gageKindScl;
156 } else if (!strcmp(gageKindVec->name, kstr)) {
157 isp->kind = gageKindVec;
158 } else if (!strcmp(tenGageKind->name, kstr)) {
159 isp->kind = tenGageKind;
160 } else {
161 biffAddf(MITEmiteBiffKey, "%s: don't recognized \"%s\" gage kind", me, kstr);
162 airMopError(mop); return 1;
163 }
164 isp->item = airEnumVal(isp->kind->enm, qstr);
165 if (0 == isp->item) {
166 biffAddf(MITEmiteBiffKey, "%s: couldn't parse \"%s\" as a %s variable",
167 me, qstr, isp->kind->name);
168 airMopError(mop); return 1;
169 }
170 }
171 } else if (strstr(buff, "mite(") == buff) {
10
Taking false branch
172 /* txf domain variable is *not* directly measured by gage */
173 if (!(endparen = strstr(buff, ")"))) {
174 biffAddf(MITEmiteBiffKey, "%s: didn't see close paren after \"mite(\"", me);
175 airMopError(mop); return 1;
176 }
177 *endparen = 0;
178 qstr = buff + strlen("mite(");
179 isp->item = airEnumVal(miteVal, qstr);
180 if (0 == isp->item) {
181 biffAddf(MITEmiteBiffKey, "%s: couldn't parse \"%s\" as a miteVal variable",
182 me, qstr);
183 airMopError(mop); return 1;
184 }
185 isp->kind = miteValGageKind;
186 } else {
187 /* didn't start with "gage(" or "mite(" */
188 isp->item = airEnumVal(miteVal, label);
189 if (0 != isp->item) {
11
Taking false branch
190 /* its measured by mite */
191 isp->kind = miteValGageKind;
192 fprintf(stderr__stderrp, "\n%s: WARNING: deprecated use of txf domain "
193 "\"%s\"; should use \"mite(%s)\" instead\n\n",
194 me, label, label);
195 } else {
196 biffAddf(MITEmiteBiffKey, "%s: \"%s\" not a recognized variable", me, label);
197 airMopError(mop); return 1;
198 }
199 }
200 airMopOkay(mop);
201 return 0;
202}
203
204void
205miteVariablePrint(char *buff, const gageItemSpec *isp) {
206 static const char me[]="miteVariablePrint";
207
208 if (!(isp->kind)) {
209 strcpy(buff, "")__builtin___strcpy_chk (buff, "", __builtin_object_size (buff
, 2 > 1 ? 1 : 0))
;
210 } else if (gageKindScl == isp->kind
211 || gageKindVec == isp->kind
212 || tenGageKind == isp->kind) {
213 sprintf(buff, "gage(%s:%s)", isp->kind->name,__builtin___sprintf_chk (buff, 0, __builtin_object_size (buff
, 2 > 1 ? 1 : 0), "gage(%s:%s)", isp->kind->name, airEnumStr
(isp->kind->enm, isp->item))
214 airEnumStr(isp->kind->enm, isp->item))__builtin___sprintf_chk (buff, 0, __builtin_object_size (buff
, 2 > 1 ? 1 : 0), "gage(%s:%s)", isp->kind->name, airEnumStr
(isp->kind->enm, isp->item))
;
215 } else if (miteValGageKind == isp->kind) {
216 sprintf(buff, "%s(%s)", isp->kind->name,__builtin___sprintf_chk (buff, 0, __builtin_object_size (buff
, 2 > 1 ? 1 : 0), "%s(%s)", isp->kind->name, airEnumStr
(isp->kind->enm, isp->item))
217 airEnumStr(isp->kind->enm, isp->item))__builtin___sprintf_chk (buff, 0, __builtin_object_size (buff
, 2 > 1 ? 1 : 0), "%s(%s)", isp->kind->name, airEnumStr
(isp->kind->enm, isp->item))
;
218 } else {
219 sprintf(buff, "(%s: unknown gageKind!)", me)__builtin___sprintf_chk (buff, 0, __builtin_object_size (buff
, 2 > 1 ? 1 : 0), "(%s: unknown gageKind!)", me)
;
220 }
221 return;
222}
223
224int
225miteNtxfCheck(const Nrrd *ntxf) {
226 static const char me[]="miteNtxfCheck";
227 char *rangeStr, *domStr;
228 gageItemSpec isp;
229 unsigned int rii, axi;
230 int ilog2;
231
232 if (nrrdCheck(ntxf)) {
233 biffMovef(MITEmiteBiffKey, NRRDnrrdBiffKey, "%s: basic nrrd validity check failed", me);
234 return 1;
235 }
236 if (!( nrrdTypeFloat == ntxf->type ||
237 nrrdTypeDouble == ntxf->type ||
238 nrrdTypeUChar == ntxf->type )) {
239 biffAddf(MITEmiteBiffKey, "%s: need a type %s, %s or %s nrrd (not %s)", me,
240 airEnumStr(nrrdType, nrrdTypeFloat),
241 airEnumStr(nrrdType, nrrdTypeDouble),
242 airEnumStr(nrrdType, nrrdTypeUChar),
243 airEnumStr(nrrdType, ntxf->type));
244 return 1;
245 }
246 if (!( 2 <= ntxf->dim )) {
247 biffAddf(MITEmiteBiffKey, "%s: nrrd dim (%d) isn't at least 2 (for a 1-D txf)",
248 me, ntxf->dim);
249 return 1;
250 }
251 rangeStr = ntxf->axis[0].label;
252 if (0 == airStrlen(rangeStr)) {
253 biffAddf(MITEmiteBiffKey, "%s: axis[0]'s label doesn't specify txf range", me);
254 return 1;
255 }
256 if (airStrlen(rangeStr) != ntxf->axis[0].size) {
257 char stmp1[AIR_STRLEN_SMALL(128+1)], stmp2[AIR_STRLEN_SMALL(128+1)];
258 biffAddf(MITEmiteBiffKey, "%s: axis[0]'s size %s, but label specifies %s values", me,
259 airSprintSize_t(stmp1, ntxf->axis[0].size),
260 airSprintSize_t(stmp2, airStrlen(rangeStr)));
261 return 1;
262 }
263 for (rii=0; rii<airStrlen(rangeStr); rii++) {
264 if (!strchr(miteRangeChar, rangeStr[rii])) {
265 biffAddf(MITEmiteBiffKey, "%s: char %d of axis[0]'s label (\"%c\") isn't a valid "
266 "transfer function range specifier (not in \"%s\")",
267 me, rii, rangeStr[rii], miteRangeChar);
268 return 1;
269 }
270 }
271 for (axi=1; axi<ntxf->dim; axi++) {
272 if (1 == ntxf->axis[axi].size) {
273 biffAddf(MITEmiteBiffKey, "%s: # samples on axis %d must be > 1", me, axi);
274 return 1;
275 }
276 domStr = ntxf->axis[axi].label;
277 if (0 == airStrlen(domStr)) {
278 biffAddf(MITEmiteBiffKey, "%s: axis[%d] of txf didn't specify a domain variable",
279 me, axi);
280 return 1;
281 }
282 if (miteVariableParse(&isp, domStr)) {
283 biffAddf(MITEmiteBiffKey, "%s: couldn't parse txf domain \"%s\" for axis %d\n",
284 me, domStr, axi);
285 return 1;
286 }
287 if (!( 1 == isp.kind->table[isp.item].answerLength ||
288 3 == isp.kind->table[isp.item].answerLength )) {
289 biffAddf(MITEmiteBiffKey, "%s: %s (item %d) not a scalar or vector "
290 "(answerLength = %d): "
291 "can't be a txf domain variable", me, domStr, isp.item,
292 isp.kind->table[isp.item].answerLength);
293 return 1;
294 }
295 if (3 == isp.kind->table[isp.item].answerLength) {
296 /* has to be right length for one of the quantization schemes */
297 ilog2 = airLog2(ntxf->axis[axi].size);
298 if (-1 == ilog2) {
299 char stmp[AIR_STRLEN_SMALL(128+1)];
300 biffAddf(MITEmiteBiffKey, "%s: txf axis size for %s must be power of 2 (not %s)",
301 me, domStr, airSprintSize_t(stmp, ntxf->axis[axi].size));
302 return 1;
303 } else {
304 if (!( AIR_IN_CL(8, ilog2, 16)((8) <= (ilog2) && (ilog2) <= (16)) )) {
305 biffAddf(MITEmiteBiffKey, "%s: log_2 of txf axis size for %s should be in "
306 "range [8,16] (not %d)", me, domStr, ilog2);
307 return 1;
308 }
309 }
310 } else {
311 if (!( AIR_EXISTS(ntxf->axis[axi].min)(((int)(!((ntxf->axis[axi].min) - (ntxf->axis[axi].min)
))))
&&
312 AIR_EXISTS(ntxf->axis[axi].max)(((int)(!((ntxf->axis[axi].max) - (ntxf->axis[axi].max)
))))
)) {
313 biffAddf(MITEmiteBiffKey, "%s: min and max of axis %d aren't both set", me, axi);
314 return 1;
315 }
316 if (!( ntxf->axis[axi].min < ntxf->axis[axi].max )) {
317 biffAddf(MITEmiteBiffKey, "%s: min (%g) not less than max (%g) on axis %d",
318 me, ntxf->axis[axi].min, ntxf->axis[axi].max, axi);
319 return 1;
320 }
321 }
322 }
323
324 return 0;
325}
326
327/*
328******** miteQueryAdd()
329**
330** This looks a given gageItemSpec and sets the bits in the
331** gageKindScl and tenGageKind queries that are required to calculate
332** the quantity
333**
334** NOTE: This does NOT initialize the query{Scl,Vec,Ten}: it
335** just adds on new items to the existing queries
336**
337** HEY: this is really unfortunate: each new gage type use for
338** volume rendering in mite will have to explicitly added as
339** arguments here, which is part of the reason that mite may end
340** up explicitly depending on the libraries supplying those gageKinds
341** (like how mite now must depend on ten)
342**
343** The queryMite argument is a little odd- its not a real gage kind,
344** but we use it to organize which of the miteVal quantities we take
345** the time to compute in miteSample().
346*/
347void
348miteQueryAdd(gageQuery queryScl, gageQuery queryVec,
349 gageQuery queryTen, gageQuery queryMite,
350 gageItemSpec *isp) {
351 static const char me[]="miteQueryAdd";
352
353 if (NULL((void*)0) == isp->kind) {
354 /* nothing to add */
355 } else if (gageKindScl == isp->kind) {
356 GAGE_QUERY_ITEM_ON(queryScl, isp->item)(queryScl[isp->item/8] |= (1 << (isp->item % 8)));
357 } else if (gageKindVec == isp->kind) {
358 GAGE_QUERY_ITEM_ON(queryVec, isp->item)(queryVec[isp->item/8] |= (1 << (isp->item % 8)));
359 } else if (tenGageKind == isp->kind) {
360 GAGE_QUERY_ITEM_ON(queryTen, isp->item)(queryTen[isp->item/8] |= (1 << (isp->item % 8)));
361 } else if (miteValGageKind == isp->kind) {
362 /* regardless of whether the mite query requires scl, vec, or ten
363 queries, we add it to the quantites that have to be computed
364 per-sample */
365 GAGE_QUERY_ITEM_ON(queryMite, isp->item)(queryMite[isp->item/8] |= (1 << (isp->item % 8))
)
;
366 /* HEY: some these have useful analogs for tensor data, but I
367 won't be able to express them. This means that while Phong
368 shading of *scalar* volumes can be implemented with transfer
369 functions, it is currently not possible in *tensor* volumes
370 (for instance, using the gradient of fractional anisotropy) */
371 switch(isp->item) {
372 case miteValVrefN:
373 case miteValNdotV:
374 case miteValNdotL:
375 /* the "N" can be a normalized vector from any of the
376 available kinds (except miteValGageKind!), and its
377 associated query will be handled elsewhere, so there's
378 nothing to add here */
379 break;
380 case miteValGTdotV:
381 GAGE_QUERY_ITEM_ON(queryScl, gageSclGeomTens)(queryScl[gageSclGeomTens/8] |= (1 << (gageSclGeomTens %
8)))
;
382 break;
383 case miteValVdefT:
384 GAGE_QUERY_ITEM_ON(queryTen, tenGageTensor)(queryTen[tenGageTensor/8] |= (1 << (tenGageTensor % 8)
))
;
385 case miteValVdefTdotV:
386 GAGE_QUERY_ITEM_ON(queryTen, tenGageTensor)(queryTen[tenGageTensor/8] |= (1 << (tenGageTensor % 8)
))
;
387 break;
388 }
389 } else {
390 fprintf(stderr__stderrp, "%s: PANIC: unrecognized non-NULL gageKind\n", me);
391 exit(1);
392 }
393 return;
394}
395
396int
397_miteNtxfCopy(miteRender *mrr, miteUser *muu) {
398 static const char me[]="_miteNtxfCopy";
399 int ni, E;
400
401 mrr->ntxf = AIR_CALLOC(muu->ntxfNum, Nrrd *)(Nrrd **)(calloc((muu->ntxfNum), sizeof(Nrrd *)));
402 if (!mrr->ntxf) {
403 biffAddf(MITEmiteBiffKey, "%s: couldn't calloc %d ntxf pointers", me, muu->ntxfNum);
404 return 1;
405 }
406 mrr->ntxfNum = muu->ntxfNum;
407 airMopAdd(mrr->rmop, mrr->ntxf, airFree, airMopAlways);
408 E = 0;
409 for (ni=0; ni<mrr->ntxfNum; ni++) {
410 mrr->ntxf[ni] = nrrdNew();
411 if (!E) airMopAdd(mrr->rmop, mrr->ntxf[ni],
412 (airMopper)nrrdNuke, airMopAlways);
413 if (!( nrrdTypeUChar == muu->ntxf[ni]->type
414 || nrrdTypeFloat == muu->ntxf[ni]->type
415 || nrrdTypeDouble == muu->ntxf[ni]->type )) {
416 biffAddf(MITEmiteBiffKey,
417 "%s: sorry, can't handle txf of type %s (only %s, %s, %s)",
418 me, airEnumStr(nrrdType, muu->ntxf[ni]->type),
419 airEnumStr(nrrdType, nrrdTypeUChar),
420 airEnumStr(nrrdType, nrrdTypeFloat),
421 airEnumStr(nrrdType, nrrdTypeDouble));
422 return 1;
423 }
424 /* note that key/values need to be copied for the sake of
425 identifying a non-default miteStageOp */
426 switch(muu->ntxf[ni]->type) {
427 case nrrdTypeUChar:
428 if (!E) E |= nrrdUnquantize(mrr->ntxf[ni], muu->ntxf[ni], nrrdTypeUChar);
429 if (!E) E |= nrrdKeyValueCopy(mrr->ntxf[ni], muu->ntxf[ni]);
430 break;
431 case mite_ntnrrdTypeDouble:
432 if (!E) E |= nrrdCopy(mrr->ntxf[ni], muu->ntxf[ni]);
433 break;
434 default: /* will be either float or double (whatever mite_nt isn't) */
435 if (!E) E |= nrrdConvert(mrr->ntxf[ni], muu->ntxf[ni], mite_ntnrrdTypeDouble);
436 if (!E) E |= nrrdKeyValueCopy(mrr->ntxf[ni], muu->ntxf[ni]);
437 break;
438 }
439 }
440 if (E) {
441 biffMovef(MITEmiteBiffKey, NRRDnrrdBiffKey, "%s: troubling copying/converting all ntxfs", me);
442 return 1;
443 }
444 return 0;
445}
446
447int
448_miteNtxfAlphaAdjust(miteRender *mrr, miteUser *muu) {
449 static const char me[]="_miteNtxfAlphaAdjust";
450 int ni, ei, ri, nnum, rnum;
451 Nrrd *ntxf;
452 mite_t *data, alpha, frac;
453
454 if (_miteNtxfCopy(mrr, muu)) {
455 biffAddf(MITEmiteBiffKey, "%s: trouble copying/converting transfer functions", me);
456 return 1;
457 }
458 frac = muu->rayStep/muu->refStep;
459 for (ni=0; ni<mrr->ntxfNum; ni++) {
460 ntxf = mrr->ntxf[ni];
461 if (!strchr(ntxf->axis[0].label, miteRangeChar[miteRangeAlpha])) {
462 continue;
463 }
464 /* else this txf sets opacity */
465 data = (mite_t *)ntxf->data;
466 rnum = ntxf->axis[0].size;
467 nnum = nrrdElementNumber(ntxf)/rnum;
468 for (ei=0; ei<nnum; ei++) {
469 for (ri=0; ri<rnum; ri++) {
470 if (ntxf->axis[0].label[ri] == miteRangeChar[miteRangeAlpha]) {
471 alpha = data[ri + rnum*ei];
472 data[ri + rnum*ei] = 1 - pow(AIR_MAX(0, 1-alpha)((0) > (1-alpha) ? (0) : (1-alpha)), frac);
473 }
474 }
475 }
476 }
477 return 0;
478}
479
480int
481_miteStageNum(miteRender *mrr) {
482 int num, ni;
483
484 num = 0;
485 for (ni=0; ni<mrr->ntxfNum; ni++) {
486 num += mrr->ntxf[ni]->dim - 1;
487 }
488 return num;
489}
490
491void
492_miteStageInit(miteStage *stage) {
493 int rii;
494
495 stage->val = NULL((void*)0);
496 stage->size = -1;
497 stage->op = miteStageOpUnknown;
498 stage->qn = NULL((void*)0);
499 stage->min = stage->max = AIR_NAN(airFloatQNaN.f);
500 stage->data = NULL((void*)0);
501 for (rii=0; rii<=MITE_RANGE_NUM9-1; rii++) {
502 stage->rangeIdx[rii] = -1;
503 }
504 stage->rangeNum = -1;
505 stage->label = NULL((void*)0);
506 return;
507}
508
509double *
510_miteAnswerPointer(miteThread *mtt, gageItemSpec *isp) {
511 static const char me[]="_miteAnswerPointer";
512 double *ret;
513
514 if (!isp->kind) {
14
Branch condition evaluates to a garbage value
515 /* we got a NULL kind (as happens with output of
516 gageItemSpecNew(), or miteVariableParse of an
517 empty string); only NULL return is sensible */
518 return NULL((void*)0);
519 }
520
521 if (gageKindScl == isp->kind) {
522 ret = mtt->ansScl;
523 } else if (gageKindVec == isp->kind) {
524 ret = mtt->ansVec;
525 } else if (tenGageKind == isp->kind) {
526 ret = mtt->ansTen;
527 } else if (miteValGageKind == isp->kind) {
528 ret = mtt->ansMiteVal;
529 } else {
530 fprintf(stderr__stderrp, "\nPANIC: %s: unknown gageKind!\n", me);
531 exit(1);
532 }
533 ret += gageKindAnswerOffset(isp->kind, isp->item);
534 return ret;
535}
536
537/*
538** _miteStageSet
539**
540** ALLOCATES and initializes stage array in a miteThread
541*/
542int
543_miteStageSet(miteThread *mtt, miteRender *mrr) {
544 static const char me[]="_miteStageSet";
545 char *value;
546 int ni, di, stageIdx, rii, stageNum, ilog2;
547 Nrrd *ntxf;
548 miteStage *stage;
549 gageItemSpec isp;
550 char rc;
551
552 stageNum = _miteStageNum(mrr);
553 /* fprintf(stderr, "!%s: stageNum = %d\n", me, stageNum); */
554 mtt->stage = AIR_CALLOC(stageNum, miteStage)(miteStage*)(calloc((stageNum), sizeof(miteStage)));
555 if (!mtt->stage) {
1
Taking false branch
556 biffAddf(MITEmiteBiffKey, "%s: couldn't alloc array of %d stages", me, stageNum);
557 return 1;
558 }
559 airMopAdd(mtt->rmop, mtt->stage, airFree, airMopAlways);
560 mtt->stageNum = stageNum;
561 stageIdx = 0;
562 for (ni=0; ni<mrr->ntxfNum; ni++) {
2
Loop condition is true. Entering loop body
563 ntxf = mrr->ntxf[ni];
564 for (di=ntxf->dim-1; di>=1; di--) {
3
Loop condition is true. Entering loop body
565 stage = mtt->stage + stageIdx;
566 _miteStageInit(stage);
567 miteVariableParse(&isp, ntxf->axis[di].label);
4
Calling 'miteVariableParse'
12
Returning from 'miteVariableParse'
568 stage->val = _miteAnswerPointer(mtt, &isp);
13
Calling '_miteAnswerPointer'
569 stage->label = ntxf->axis[di].label;
570 /*
571 fprintf(stderr, "!%s: ans=%p + offset[%d]=%d == %p\n", me,
572 mtt->ans, dom, kind->ansOffset[dom], stage->val);
573 */
574 stage->size = ntxf->axis[di].size;
575 stage->min = ntxf->axis[di].min;
576 stage->max = ntxf->axis[di].max;
577 if (di > 1) {
578 stage->data = NULL((void*)0);
579 } else {
580 stage->data = (mite_t *)ntxf->data;
581 value = nrrdKeyValueGet(ntxf, "miteStageOp");
582 if (value) {
583 stage->op = airEnumVal(miteStageOp, value);
584 if (miteStageOpUnknown == stage->op) {
585 stage->op = miteStageOpMultiply;
586 }
587 } else {
588 stage->op = miteStageOpMultiply;
589 }
590 if (1 == isp.kind->table[isp.item].answerLength) {
591 stage->qn = NULL((void*)0);
592 } else if (3 == isp.kind->table[isp.item].answerLength) {
593 char stmp[AIR_STRLEN_SMALL(128+1)];
594 ilog2 = airLog2(ntxf->axis[di].size);
595 switch(ilog2) {
596 case 8: stage->qn = limnVtoQN_d[ limnQN8octa]; break;
597 case 9: stage->qn = limnVtoQN_d[ limnQN9octa]; break;
598 case 10: stage->qn = limnVtoQN_d[limnQN10octa]; break;
599 case 11: stage->qn = limnVtoQN_d[limnQN11octa]; break;
600 case 12: stage->qn = limnVtoQN_d[limnQN12octa]; break;
601 case 13: stage->qn = limnVtoQN_d[limnQN13octa]; break;
602 case 14: stage->qn = limnVtoQN_d[limnQN14octa]; break;
603 case 15: stage->qn = limnVtoQN_d[limnQN15octa]; break;
604 case 16: stage->qn = limnVtoQN_d[limnQN16octa]; break;
605 default:
606 biffAddf(MITEmiteBiffKey, "%s: txf axis %d size %s not usable for "
607 "vector txf domain variable %s", me, di,
608 airSprintSize_t(stmp, ntxf->axis[di].size),
609 ntxf->axis[di].label);
610 return 1;
611 break;
612 }
613 } else {
614 biffAddf(MITEmiteBiffKey, "%s: %s not scalar or vector (len = %d): can't be "
615 "a txf domain variable", me,
616 ntxf->axis[di].label,
617 isp.kind->table[isp.item].answerLength);
618 return 1;
619 }
620 stage->rangeNum = ntxf->axis[0].size;
621 for (rii=0; rii<stage->rangeNum; rii++) {
622 rc = ntxf->axis[0].label[rii];
623 stage->rangeIdx[rii] = strchr(miteRangeChar, rc) - miteRangeChar;
624 /*
625 fprintf(stderr, "!%s: range: %c -> %d\n", "_miteStageSet",
626 ntxf->axis[0].label[rii], stage->rangeIdx[rii]);
627 */
628 }
629 }
630 stageIdx++;
631 }
632 }
633 return 0;
634}
635
636void
637_miteStageRun(miteThread *mtt, miteUser *muu) {
638 static const char me[]="_miteStageRun";
639 int stageIdx, ri, rii;
640 unsigned int txfIdx, finalIdx;
641 miteStage *stage;
642 mite_t *rangeData;
643 double *dbg=NULL((void*)0);
644
645 finalIdx = 0;
646 if (mtt->verbose) {
647 dbg = muu->debug + muu->debugIdx;
648 }
649 for (stageIdx=0; stageIdx<mtt->stageNum; stageIdx++) {
650 stage = &(mtt->stage[stageIdx]);
651 if (stage->qn) {
652 /* its a vector-valued txf domain variable */
653 txfIdx = stage->qn(stage->val);
654 /* right now, we can't store vector-valued txf domain variables */
655 } else {
656 /* its a scalar txf domain variable */
657 txfIdx = airIndexClamp(stage->min, *(stage->val),
658 stage->max, stage->size);
659 if (mtt->verbose) {
660 fprintf(stderr__stderrp, "!%s: %s=%g in [%g,%g]/%u -> %u\n", me,
661 stage->label, *(stage->val),
662 stage->min, stage->max, stage->size, txfIdx);
663 dbg[0 + 2*stageIdx] = *(stage->val);
664 }
665 }
666 finalIdx = stage->size*finalIdx + txfIdx;
667 if (mtt->verbose) {
668 dbg[1 + 2*stageIdx] = txfIdx;
669 }
670 if (stage->data) {
671 rangeData = stage->data + stage->rangeNum*finalIdx;
672 for (rii=0; rii<stage->rangeNum; rii++) {
673 ri = stage->rangeIdx[rii];
674 switch(stage->op) {
675 case miteStageOpMin:
676 mtt->range[ri] = AIR_MIN(mtt->range[ri], rangeData[rii])((mtt->range[ri]) < (rangeData[rii]) ? (mtt->range[ri
]) : (rangeData[rii]))
;
677 break;
678 case miteStageOpMax:
679 mtt->range[ri] = AIR_MAX(mtt->range[ri], rangeData[rii])((mtt->range[ri]) > (rangeData[rii]) ? (mtt->range[ri
]) : (rangeData[rii]))
;
680 break;
681 case miteStageOpAdd:
682 mtt->range[ri] += rangeData[rii];
683 break;
684 case miteStageOpMultiply:
685 default:
686 mtt->range[ri] *= rangeData[rii];
687 break;
688 }
689 }
690 finalIdx = 0;
691 }
692 }
693 return;
694}